Can someone explain collection_select to me in clear, simple terms?
I am going through the Rails API docs for collection_select
and they are god-awful.
The heading is this:
collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
And this is the only sample code they give:
collection_select(:post, :author_id, Author.all, :id, :name_with_initial, :prompt => true)
Can someone explain, using a simple association (say a User
has_many Plans
, and a Plan
belongs to a User
), what I want to use in the syntax and why?
Edit 1: Also, it would be awesome if you explained how it works inside a form_helper
or a regular form. Imagine you are explaining this to a web developer that understands web development, but is 'relatively new' to Rails. How would you explain it?
Solution 1:
collection_select(
:post, # field namespace
:author_id, # field name
# result of these two params will be: <select name="post[author_id]">...
# then you should specify some collection or array of rows.
# It can be Author.where(..).order(..) or something like that.
# In your example it is:
Author.all,
# then you should specify methods for generating options
:id, # this is name of method that will be called for every row, result will be set as key
:name_with_initial, # this is name of method that will be called for every row, result will be set as value
# as a result, every option will be generated by the following rule:
# <option value=#{author.id}>#{author.name_with_initial}</option>
# 'author' is an element in the collection or array
:prompt => true # then you can specify some params. You can find them in the docs.
)
Or your example can be represented as the following code:
<select name="post[author_id]">
<% Author.all.each do |author| %>
<option value="<%= author.id %>"><%= author.name_with_initial %></option>
<% end %>
</select>
This isn't documented in the FormBuilder
, but in the FormOptionsHelper
Solution 2:
I've spent quite some time on the permutations of the select tags myself.
collection_select
builds a select tag from a collection of objects. Keeping this in mind,
object
: Name of the object. This is used to generate the name of the tag, and is used to generate the selected value. This can be an actual object, or a symbol - in the latter case, the instance variable of that name is looked for in the binding of the ActionController
(that is, :post
looks for an instance var called @post
in your controller.)
method
: Name of the method. This is used to generate the name of the tag.. In other words, the attribute of the object you are trying to get from the select
collection
: The collection of objects
value_method
: For each object in the collection, this method is used for value
text_method
: For each object in the collection, this method is used for display text
Optional Parameters:
options
: Options that you can pass. These are documented here, under the heading Options.
html_options
: Whatever is passed here, is simply added to the generated html tag. If you want to supply a class, id, or any other attribute, it goes here.
Your association could be written as:
collection_select(:user, :plan_ids, Plan.all, :id, :name, {:prompt => true, :multiple=>true })
With regards to using form_for
, again in very simple terms, for all tags that come within the form_for
, eg. f.text_field
, you dont need to supply the first (object
) parameter. This is taken from the form_for
syntax.