Чи може хтось пояснити мені 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і Planналежить a User), що я хочу використовувати в синтаксисі і чому?

Редагувати 1: Крім того, було б дивним, якби ви пояснили, як це працює всередині form_helperзвичайної форми чи звичайної форми. Уявіть, що ви пояснюєте це веб-розробнику, який розуміє веб-розробку, але "відносно новий" для Rails. Як би ви це пояснили?


50
Так. Це найжахливіша документація, яку я коли-небудь бачив
Jaseem

1
Чесно кажучи, документація цілком нормальна, тільки не в, FormBuilderале в FormOptionsHelper: api.rubyonrails.org/classes/ActionView/Helpers/…
amiuhle

1
Моя улюблена частина - це коли ви використовуєте collection_select у формі, і це змінює всю підпис, щоб об'єкт не був частиною списку параметрів, а натомість collection_select викликається як метод на об'єкті. Не думаю, що вони згадують про це в документах ...
user3670743

1
Це проект із відкритим кодом: якщо документація погана, ми винні лише самі; це може бути дивовижно, якби ми лише зробили все, щоб зробити його кращим. Невеликі / прості піарники проходять довгий шлях.
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


32
Це легко, одне з найкращих пояснень складної структури Rails, яку я бачив. Ви використали чітку мову, а також основні конструкції Rails для її затвердження. Велике спасибі !!
маркальйон

2
Чому б ви коли-небудь називали це "post [author_id]"?
Jaseem

@alexkv дякую - чи зможете ви детальніше розібратися у значущості: post, # простору імен поля та: author_id, # параметрів імені поля (перші два) - я не розумію їх призначення в схемі речей - може " t їх опустити?
BKSpurgeon

1
Перший парам справді може бути нульовим. Якщо ви створюєте об'єктну форму, це буде той об'єкт, щоб у виділення був такий самий проміжок імен, що й у решти форми. Якщо це не потрібно, залиште 1-го як нульовим. 2-е - це назва елемента керування, тому, якщо потрібно оновити поле на об'єкті (1-й параметр), то ім'я поля є другим параметром. Якщо ви створюєте якусь форму для іншого використання, другий параметр - це те, що ви хочете, щоб контроль форми був названий і ідентифікований. Навіщо використовувати це з нулем 1-го? Можливо, тому, що ви хочете collection_select для параметрів: prompt.
elc

1
Я також повинен зазначити, що ви можете отримати той самий ефект, позначаючи параметр підказок на select_tag, який використовує options_for_select, який, ймовірно, відповідатиме так само, як collection_select з об'єктом нуля.
elc

21

Я витратив досить багато часу на перестановки вибраних тегів.

collection_selectбудує виділений тег із колекції об’єктів. Маючи це на увазі,

object: Назва об'єкта. Він використовується для генерації імені тегу і використовується для генерації вибраного значення. Це може бути фактичний об'єкт або символ - в останньому випадку змінну екземпляра цього імені шукають у прив'язціActionController (тобто :postшукає екземпляр var, викликаний @postу вашому контролері.)

method: Назва методу. Це використовується для генерування імені тегу. Іншими словами, атрибут об'єкта, який ви намагаєтеся отримати з вибору

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синтаксису.


2
Дякуємо, що знайшли час ... Хоча єдине питання - це, чесно кажучи, ваше пояснення не допомагає з’ясувати речі в моїй голові. Ви використовували багато термінів у фактичному визначенні. Я дуже ціную, що ви витратили час - тому за це я і проголосував.
Маркальйон

4
З причин, настільки чітко викладених marcamillion, я проголосував за це.
Джеймі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.