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

146

Я просматриваю документы по 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)

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

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

marcamillion
источник
50
Да. Это самая ужасная документация, которую я когда-либо видел
Jaseem
1
Справедливости ради, с документацией все в порядке, только не в, FormBuilderа в FormOptionsHelper: api.rubyonrails.org/classes/ActionView/Helpers/…
amiuhle
1
Моя любимая часть - когда вы используете collection_select в форме, и это изменяет всю подпись, так что объект не является частью списка параметров, а вместо этого collection_select вызывается как метод объекта. Не думайте, что они упоминают это в документах ...
user3670743
1
Это проект с открытым исходным кодом: если документация плохая, мы должны винить только самих себя; это может быть удивительно, если только мы сделаем все возможное, чтобы сделать его лучше. Маленькие / простые PR имеют большое значение.
BKSpurgeon

Ответы:

305
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

alexkv
источник
32
Это легко, одно из лучших объяснений сложной структуры Rails, которую я видел. Вы использовали понятный язык вместе с базовыми конструкциями Rails, чтобы закрепить его. Большое спасибо!!
Marcamillion
2
Почему вы бы назвали это "post [author_id]"?
Джасим
@alexkv спасибо - не могли бы вы рассказать о значении: post, # namespace field и: author_id, # namename параметров (первые два) - я не понимаю их назначение в схеме вещей - can ' они не должны быть опущены?
BKSpurgeon
1
Первый параметр действительно может быть нулем. Если вы создаете объектную форму, это будет тот объект, так что выбор имеет то же пространство имен, что и остальная часть формы. Если это не нужно, оставьте 1 как ноль. 2nd - это имя элемента управления, поэтому если оно обновляет поле объекта (1-й параметр), то имя поля является вторым параметром. Если вы создаете какую-то форму для других целей, 2-й параметр - это то, что вы хотите, чтобы элемент управления формы был назван и идентифицирован. Зачем использовать это с ноль 1-й? Возможно, потому что вы хотите collection_select для опций: prompt.
Elc
1
Я также должен отметить, что вы можете получить тот же эффект, прикрепив параметр подсказки к select_tag, использующему options_for_select, который, скорее всего, ответит так же, как collection_select с нулевым объектом.
Elc
21

Я потратил довольно много времени на перестановку тегов select самостоятельно.

collection_selectсоздает тег выбора из коллекции объектов. Имея это в виду,

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

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

collection : Коллекция предметов

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

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

Необязательные параметры:

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

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

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

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

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

zsquare
источник
2
Спасибо, что нашли время ... единственная проблема, честно говоря, ваше объяснение не помогает прояснить вещи в моей голове. Вы использовали много терминов в фактическом определении. Я действительно ценю, что вы нашли время - так что за это я проголосовал за него.
Marcamillion
4
По причинам, ясно изложенным marcamillion, я проголосовал за него.
Джейми