Can someone explain collection_select to me in cle

2019-01-03 19:42发布

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?

2条回答
三岁会撩人
2楼-- · 2019-01-03 20:11

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.

查看更多
爷的心禁止访问
3楼-- · 2019-01-03 20:15
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

查看更多
登录 后发表回答