Может ли кто-нибудь объяснить collection_select мне в ясных, простых выражениях?

Я просматриваю документы Rails API для collection_select, и они ужасны.

Заголовок таков:

collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})

И это единственный пример кода, который они дают:

collection_select(:post, :author_id, Author.all, :id, :name_with_initial, :prompt => true)

Может кто-нибудь объяснить, используя простую ассоциацию (скажем, User has_many Plans, а Plan принадлежит User), что я хочу использовать в синтаксисе и почему?

Изменить 1:. Было бы замечательно, если бы вы объяснили, как это работает внутри form_helper или обычной формы. Представьте, что вы объясняете это веб-разработчику, который понимает веб-разработку, но является "относительно новым" для Rails. Как бы вы это объяснили?

Ответ 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.
)

Или ваш пример может быть представлен в виде следующего кода:

<select name="post[author_id]">
    <% Author.all.each do |author| %>
        <option value="<%= author.id %>"><%= author.name_with_initial %></option>
    <% end %>
</select>

Это не описано в FormBuilder, но в FormOptionsHelper

Ответ 2

Я потратил довольно много времени на перестановки выбранных тегов.

collection_select строит тег select из коллекции объектов. Помня об этом,

object: имя объекта. Это используется для генерации имени тега и используется для генерации выбранного значения. Это может быть фактический объект или символ - в последнем случае переменная экземпляра этого имени искала в привязке ActionController (т.е. :post ищет экземпляр var, называемый @post в вашем контроллере.)

method: имя метода. Это используется для генерации имени тега. Другими словами, атрибут объекта, который вы пытаетесь получить из select

collection: коллекция объектов

value_method: для каждого объекта в коллекции этот метод используется для значения

text_method: для каждого объекта в коллекции этот метод используется для отображения текста

Дополнительные параметры:

options: параметры, которые вы можете передать. Они описаны здесь в разделе "Параметры".

html_options: Все, что здесь передается, просто добавляется в сгенерированный тег html. Если вы хотите предоставить класс, id или любой другой атрибут, он будет здесь.

Ваша ассоциация может быть записана как:

collection_select(:user, :plan_ids, Plan.all, :id, :name, {:prompt => true, :multiple=>true })

Что касается использования form_for, опять же в очень простых терминах, для всех тегов, которые входят в form_for, например. f.text_field, вам не нужно указывать первый (object) параметр. Это берется из синтаксиса form_for.