views:

311

answers:

2

I'm trying to create a <select> element using the collection_select method, but it seems that in order for the proper <option> to be selected, the identifier passed into collection_select needs to be an instance variable and not a local variable (this is happening in a partial).

So when I create a <select> for the categories of a product, the proper category is NOT selected by default.

_product_row.erb (DOES NOT WORK):

My product: <%= product.name %>
<%= collection_select(:product, :category_id, @current_user.categories, :id, :name, options = {:prompt => "-- Select a category --"}) %>

Screenshot:

alt text

I discovered that I was able to get it to work by declaring an instance variable before hand, but this seems like a huge hack to me.

_product_row.erb (WORKS):

<% @product_select_tmp = product %>
<%= collection_select(:product_select_tmp, :category_id, @current_user.categories, :id, :name, options = {:prompt => "-- Select a category --"}) %>

Screenshot:

alt text

Because this partial is iterating over a collection of products, I can't just have @product declared in the controller (IOW unless I'm missing something, product must be a local variable in this partial).

So how do I get collection_select to select the appropriate item when calling it with a local variable?

+1  A: 

You can pass collections to partials and designate a local variable to pass them as:

<%= render :partial => "products/product_row", :collection => @products, :as => :products %>

Relevant documentation: http://apidock.com/rails/ActionView/Partials

Damien Wilson
Thanks... but that doesn't really solve the problem.
mmacaulay
You wanted a way to get the instance variable `@products` without having to explicitly declare it, correct? Passing in the desired collection through `render :partial ... :collection => @collection` should do the trick. You'll need the entire collection if you want to have a dropdown in each product table row anyway. Or am I misunderstanding the question?
Damien Wilson
No, I want to be able to call collection_select with a _local_ variable, not an instance variable, and have the right option be selected in the resulting HTML. Sorry, I realize the question is kind of confusing. Maybe I'll try to re-word it.
mmacaulay
Oh, well, if that's the case all you need to do is call `render :partial ... :collection => @collection, :as => :local_variable`. I'll update my answer accordingly.
Damien Wilson
Hi Damien, thanks, I did not know you could render a partial with a collection like that! Great tip. It still doesn't solve the problem though. I've re-worded my question in hopes of making it clearer.
mmacaulay
+1  A: 

Have you tried passing in the :selected key in the options hash? If you provide it with the current product.id it should behave the way you're expecting.

<%= collection_select(:product, :category_id, @current_user.categories, :id, :name, {:prompt => "-- Select a category --", :selected => product.category.id}) %>

Damien Wilson
Figured I'd add this as it's own answer as the last one seems to have been useful in and off itself, despite not quite being what you were looking for.
Damien Wilson
Thanks again Damien, that seems to have done the trick, although it should be :selected => product.category.id. If you update your answer I'll mark it as accepted. It's worth noting that the :prompt option will still be present in the dropdown in this scenario (rails is smart enough to leave it out of the options if you use the method in the second example in my question), but I can live with that :)
mmacaulay
Done and done. Happy coding.
Damien Wilson