i was writing code to append new email to an empty array in my Rails App. like this:
#users_email = Array.new
#users_email << User.find_by_id(#comment.user_id).email
#users_email << User.find_by_id(Comment.find_by_id(#parent_id).user_id).email if !#parent_id.nil?
Note: Here #comment is just a hash of id, user_id, parent_id and #parent_id is a the id of a Parent of any Comment. as in Hierarchy of Parent-child.
But instead of having two items in array ex: ["ak#xyz.com", "aks#xyz.com"] I am getting only one item ex:["aks#xyz.com"] after appending second item.
My confusion starts when I try to save above expression in an Instance variable and tries to append the same into an empty array, It behaves as expected.
Ex:
#users_email = Array.new
#first = User.find_by_id(#comment.user_id).email
#second = User.find_by_id(Comment.find_by_id(#parent_id).user_id).email if !#parent_id.nil?
#users_email << #first # ["ak#xyz.com"]
#users_email << #second # ["ak#xyz.com", "aks#xyz.com"]
where as this wasn't the case in previous one.
Can someone please explain whats happening here.
Update
By mistake I have place "=" instead of "<<" while appending first element to the array for the first case and after appending second one I got the result something like "ak#xyz.comaks#xyz.com" but for some reason in my Rails Application I was getting only the first email id in return.ex: ["ak#xyz.com"]
So, probably this question is now not relevant to the issue raised. Sorry for bugging all of you.
That's because you have this check !#parent_id.nil? at the end of the following statement:
#users_email << User.find_by_id(Comment.find_by_id(#parent_id).user_id).email if !#parent_id.nil?
In the first case, #parent_id apparently is nil, so the statement never executes: hence only one value is appended to the array.
Aside: prefer using the array literal syntax (ary = [] over ary = Array.new)
Related
I have a column in Company, that is serialized as Array:
class Company
serialize :column_name, Array
end
In rails console, when I try the following:
existing = Company.last.column_name
# it gives a array with single element, say [1]
existing.delete(1)
# now existing is []
Company.last.update_attributes!(column_name: existing)
# It empties the array, so:
Company.last.column_name #gives []
But, when I try the same code in remove method of some controller, it never removes the last element. It always returns [1].
How can I empty the serialized column?
NOTE:- This logic works when I have multiple elements, but doesn't work for the last element alone.
CONTROLLER CODE
def remove_restricted_num
company = Company.where(id: params[:id]).first
restricted_numbers = company.restricted_numbers
num = params[:num].to_i
if restricted_numbers.include?(num)
restricted_numbers.delete(num)
company.update_attributes!(restricted_numbers: restricted_numbers)
render js: "alert('#{num} was removed')"
else
render js: "alert('Number not found in the list')"
end
end
I got the fix, we need to use dup to get a independent variable existing, which otherwise was referencing Company.last.column_name
existing = Company.last.column_name.dup # THIS WORKS!!!
existing.delete(1)
Company.last.update_attributes!(column_name: existing)
This updates the column to [], as I need.
This is a custom rake task file, if that makes a difference.
I want to pull all user_id's from Pupil, and apply them to get the User.id for all pupils.
It happily prints out line 2 with correct user_id, but then considers user_id a 'method' and breaks on line 3. Why? Where is my mistake?
course_pupils = Pupil.where(course_id: study.course_id)
course_pupils.map { |a| puts a.user_id }
pupils = User.where(id: course_pupils.user_id )
course_pupils is still a relation when you are calling it in line 3. Line 2 is non destructive (and if it was, it would turn it into an array of nils because puts returns nil).
You need to do:
pupils = User.where(id: course_pupils.pluck(:user_id) )
Or something like that
You are doing it wrong, you cannot call an instance method user_id on a collection, try this instead
user_ids = Pupil.where(course_id: study.course_id).pluck(:user_id)
pupils = User.where(id: user_ids )
Hope that helps!
I have the following controller action that builds two arrays.
current_event = Event.find(params[:event_id])
campaign_titles = Relationship::CampaignTitleRelationship.where(campaign_id: current_event.campaign_id)
campaign_title_ids = Array.new
campaign_titles.each do |title|
campaign_title_ids << [title.title_id]
end
event_title_ids = Array.new
params[:title_ids].each do |title|
event_title_ids << [title]
end
The two arrays output like this
[["6556"], ["9359"], ["11319"], ["12952"], ["14389"], ["14955"], ["16823"]]
[[6556], [9359], [11319], [12952], [14389], [14955], [16823]]
I'm trying to compare these two arrays using the - symbol, but am only getting an output of each id, instead of what I expect (nothing) since both arrays contain the same items.
I can see that the first array has quotations around each key inside the bracket. The second does not. How do I compare these two arrays?
Just add params as integers to your array
params[:title_ids].each do |title|
event_title_ids << [title.to_i]
end
I want to assign_attribute to various rows in a table and then save them together in a loop. So here is how I am trying to do,
player_arr = []
params[:player_types].each do |index,p_type_params|
if p_type_params[:id]
player_arr << #player_types.find(p_type_params[:id]).assign_attributes(p_type_params)
end
end
Later I wish to do a save atomically on all the updates as a transaction,
ActiveRecord::Base.transaction do
player_arr.each do |p_type|
p_type.save
end
end
But this does not seem to work as p_type seems to be NilClass. I dont understand why because when I do player_arr.length I get a positive number.
Also the goal here is to capture all the assignment errors in the first loop and then do an atomic save. Ofcourse I can save in the first loop itself but it will capture only the first encountered error. Any pointers will be really helpful
The problem seems to be that you are doing too much in one line.
player_arr << #player_types.find(p_type_params[:id]).assign_attributes(p_type_params)
Here you are adding the return value of assign_attributes (nil) to the player_arr array.
Do this instead:
player_arr = []
params[:player_types].each do |index,p_type_params|
if p_type_params[:id]
player = #player_types.find(p_type_params[:id])
player.assign_attributes(p_type_params)
player_arr << player
end
end
I'm trying to create a list of recipients to send in an external request by assigning it to a variable by doing the following:
recipients = #items.each do |item|
{"email"=>"#{Recipient.find_by_id(item.recip_id).email}", "amount"=>"#{item.price}"},
end
but I'm getting this error:
syntax error, unexpected ',', expecting '}'
I know that what I've done is not the right syntax. I'm kind of a Ruby newbie, so can someone help me figure out the correct syntax here?
EDIT: Thanks for the input. But what if I need to do two hashes for each item?
recipients = #items.map do |item|
{"email"=>"#{Recipient.find_by_id(item.recip_id).email}", "amount"=>"#{item.price}"},
{"email"=>"#{Store.find_by_id(item.recip_id).email}", "amount"=>"#{item.price}"}
end
The problem is with the comma at the end of the hash. Also if you want to store the email and amount in recipients, you should use map. This will return an array of hash with email and amount:
recipients = #items.map do |item|
{"email"=> Recipient.find_by_id(item.recip_id).email, "amount"=> item.price}
end
Also, as you might note, I don't need to pass the values of email and prices as a string.
If you want to return multiple hashes from your map block then you'd be better off switching to each_with_object:
Iterates the given block for each element with an arbitrary object given, and returns the initially given object.
So something like this:
recipients = #items.each_with_object([]) do |item, a|
a << {"email"=>"#{Recipient.find_by_id(item.recip_id).email}", "amount"=>"#{item.price}"}
a << {"email"=>"#{Store.find_by_id(item.recip_id).email}", "amount"=>"#{item.price}"}
end