1

The following array ["2", "8", "134", "137", "140"] is generated via user input. The controller action invokes the arrays as follows:

params[:product_ids].each do |product_id|
  @product = Product.where('id = ?', product_id).first
end 

Unfortunately when calling the values in the view (for development control purposes)

<% params[:product_ids].each do |t| %>
  <%= t %> <%= @product.id %><br />
<% end %>

is rendering the proper value for t but is then associating it with 140 five times.

2 140
8 140
134 140
137 140
140 140

thus accessing the LAST item of the array and ignoring the key. When this is attempted in the controller:

params[:product_ids].each do |k, product_id|

it is returning Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id

How can the controller be defined to appropriately access the parameter's value?

0

3 Answers 3

2

You are assinging the values in a loop to the same variable, put it outside the loop, and use #map to get values as a Transaction model for all product ids, so:

@transactions = params[:product_ids].map do |product_id|
   [ Transaction.where(product_id: product_id).first ]
end

and then:

<%= @transactions %>
Sign up to request clarification or add additional context in comments.

7 Comments

@Malo. This syntax does generate data. What surprised me is that <%= @products %> returned ["2", #<Product id: 2, struttura_id: 1, [...] ["8", #<Product id: 8, struttura_id: 1, etc. In other words, the value, followed by the object's data. Then if I want to loop through each and create new records @products.each do |product| params[:transaction][:product_id] = product.id @transaction = Transaction.new(params[:transaction] I cannot as this is accessing an array...
@Jerome well, and what did you want to get? =)
@Malo The Product's id... But I believe my reasoning has fallen into a circular trap. It would've been more direct to have gone with params[:product_ids].each do |product_id| params[:transaction][:product_id] @transaction = Transaction.new(params[:transaction] ...
@Jerome what product's did you wish to get?
one transaction per param[:product_id]
|
2

In this piece of code:

params[:product_ids].each do |product_id|
  @product = Product.where('id = ?', product_id).first
end

You're updating @product instance variable n times (where n is size of params[:product_ids] table). At the end, @product instance variable holds Product with id which is last element of params[:product_ids], in your case it's 140. I guess it would be better if you set products array, like this:

@products = Product.where(id: params[:product_ids])

so you could iterate over them:

<% @products.each do |product| %>
  <%= product.id %>
<% end %>

5 Comments

Is this syntax Product.where(id: params[:product_ids]) correct? I haven't come across it before?
@Jerome it's correct. It generates SQL with IN clause.
this is generating Product Load (2.7ms) SELECT "products".* FROM "products" WHERE "products"."id" IS NULL and only once... (postgresql is db)
@Jerome So your params[:product_ids] is probably nil.
Not really. <%= params[:product_ids] %> returns ` ["2", "8", "134", "137", "140"] `
0

When you use

params[:product_ids].each do |product_id|
  @product = Product.where('id = ?', product_id).first
end 
# you set @product = 2
# @product = 8
# ...
# @product = 140  last value of @product is 140

solution

@products = params[:product_ids].map do |p_id|
   {p_id => Product.find_by(id: p_id)}    
end

In your view

<% @products.each do |k, v| %>
  <%= k %> <%= v %><br />
<% end %>

4 Comments

Product.find_by(p_id) won't work. It should be either Product.find_by(id: p_id) or Product.find_by_id(p_id).
nope, find_by without column name doesn't behave like find_by(id: p_id), at least in 4.1.6.
You are right, I was not looking carefully, it returns first object from DB
... or simply raises an error, if you use postgresql for example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.