Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby on Rails Collection select - how to pre-select the right value?

I spent the last three days working on the collection _ select form helper for my "listing" - form, where users can select a category.

I would like to have the category currently set in listing.category_id as the preselected value.

My view code looks like this:

<%= l.collection_select(:category_id, @category, :id, :name, options = {},
                        html_options = {:size => 10, :selected => @listing.category_id.to_s})%>

I know this is not correct, but even reading looking at the explanation from Shiningthrough (http://shiningthrough.co.uk/blog/show/6) I can not understand how to proceed.

Thank you for your support,

Michael

View: as above
Controller:

def categories #Step 2
@listing = Listing.find(params[:listing_id])
@seller = Seller.find(@listing.seller_id)
@category = Category.find(:all)
@listing.complete = "step1"

respond_to do |format|
  if @listing.update_attributes(params[:listing])
    flash[:notice] = 'Step one succesful. Item saved.'
    format.html #categories.html.erb
end
end
end
like image 546
Michael Schmitz Avatar asked Jun 30 '09 18:06

Michael Schmitz


1 Answers

collection_select doesn't support the selected option, in fact, it doesn't need it. It automatically selects the option whose value matches the value of the form builder object.

Let me show you an example. Assuming each post belongs to a category.

@post = Post.new

<% form_for @post do |f| %>
  <!-- no option selected -->
  <%= f.collection_select :category_id, Category.all, :id, :name, :prompt => true  %>
<% end %>

@post = Post.new(:category_id => 5)

<% form_for @post do |f| %>
  <!-- option with id == 5 is selected -->
  <%= f.collection_select :category_id, Category.all, :id, :name, :prompt => true  %>
<% end %>

EDIT:

I'd suggest to use representative variable names. Use @categories instead of @category. :) Also, split the update logic from the read-only view.

def categories #Step 2
  @listing = Listing.find(params[:listing_id])
  @seller = Seller.find(@listing.seller_id)
  @categories = Category.find(:all)
  @listing.complete = "step1"

  respond_to do |format|
    if @listing.update_attributes(params[:listing])
      flash[:notice] = 'Step one succesful. Item saved.'
      format.html #categories.html.erb
    end
  end
end

<% form_for @listing do |f| %>
  <%= f.collection_select :category_id, @categories, :id, :name, :prompt => true %>
<% end %>

If it doesn't work (that is it selects the prompt) it means either you don't have a category_id associated to that record or the Category collection is empty. Be sure to not reset the value of category_id for @listing somewhere before the object is passed to the form.

EDIT 2:

class Category
  def id_as_string
    id.to_s
  end
end

<%= f.collection_select :category_id, Category.all, :id_as_string, :name, :prompt => true  %>
like image 179
Simone Carletti Avatar answered Oct 21 '22 13:10

Simone Carletti