Dapatkah seseorang menjelaskan collection_select kepada saya dengan istilah yang jelas dan sederhana?

146

Saya akan menelusuri Rails API docs for collection_selectdan mereka mengerikan sekali.

Judulnya adalah ini:

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

Dan ini adalah satu-satunya kode sampel yang mereka berikan:

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

Dapatkah seseorang menjelaskan, menggunakan asosiasi sederhana (katakanlah Userhas_many Plans, dan Planmilik a User), apa yang ingin saya gunakan dalam sintaks dan mengapa?

Sunting 1: Juga, akan luar biasa jika Anda menjelaskan cara kerjanya di dalam form_helperatau bentuk biasa. Bayangkan Anda menjelaskan hal ini kepada pengembang web yang memahami pengembangan web, tetapi 'relatif baru' untuk Rails. Bagaimana Anda menjelaskannya?

marcamillion
sumber
50
Iya. Itu adalah dokumentasi paling mengerikan yang pernah saya lihat
Jaseem
1
Agar adil, dokumentasinya cukup ok, tidak hanya di FormBuildertetapi di FormOptionsHelper: api.rubyonrails.org/classes/ActionView/Helpers/…
amiuhle
1
Bagian favorit saya adalah ketika Anda menggunakan collection_select dalam formulir dan itu mengubah seluruh tanda tangan sehingga objek bukan bagian dari daftar parameter tetapi sebaliknya collection_select disebut sebagai metode pada objek. Jangan kira mereka menyebutkan itu di dokumen ...
user3670743
1
Ini adalah proyek open source: jika dokumentasinya buruk, kita hanya bisa menyalahkan diri sendiri; itu bisa luar biasa kalau saja kita mau melakukan sedikit untuk membuatnya lebih baik. PR kecil / sederhana sangat membantu.
BKSpurgeon

Jawaban:

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.
)

Atau contoh Anda dapat direpresentasikan sebagai kode berikut:

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

Ini tidak didokumentasikan di FormBuilder, tetapi diFormOptionsHelper

alexkv
sumber
32
Ini mudah, salah satu penjelasan terbaik dari struktur Rails kompleks yang pernah saya lihat. Anda menggunakan bahasa yang jelas, bersama dengan konstruksi Rail dasar untuk memantapkannya. Terimakasih banyak!!
marcamillion
2
Mengapa Anda akan menamainya "memposting [author_id]"?
Jaseem
@alexkv terima kasih - dapatkah Anda menguraikan pentingnya: posting, # bidang namespace dan: author_id, # parameter nama bidang (dua yang pertama) - Saya tidak mengerti tujuan mereka dalam skema hal - bisa ' t mereka dihilangkan?
BKSpurgeon
1
Param pertama memang bisa nol. Jika Anda membuat bentuk objek, objek itu akan menjadi sehingga pemilihan memiliki namespace yang sama dengan sisa formulir. Jika itu tidak diperlukan, biarkan 1 sebagai nihil. Yang ke-2 adalah nama kontrol, jadi jika itu untuk memperbarui bidang pada objek (parameter 1) maka nama bidang adalah parameter kedua. Jika Anda membuat beberapa formulir untuk penggunaan lain, parameter ke-2 adalah apa pun yang Anda inginkan untuk kontrol bentuknya dinamai dan id'd. Mengapa menggunakan ini dengan nil 1? Mungkin karena Anda ingin collection_select untuk opsi: prompt.
elc
1
Saya juga harus mencatat bahwa Anda bisa mendapatkan efek yang sama dengan memasang parameter prompt ke select_tag yang menggunakan options_for_select, yang kemungkinan akan menjawab sama dengan collection_select dengan objek nil.
elc
21

Saya telah menghabiskan beberapa waktu pada permutasi dari tag pilih sendiri.

collection_selectmembangun tag pilih dari kumpulan objek. Ingatlah ini,

object: Nama objek. Ini digunakan untuk menghasilkan nama tag, dan digunakan untuk menghasilkan nilai yang dipilih. Ini bisa berupa objek aktual, atau simbol - dalam kasus terakhir, variabel instance dari nama tersebut dicari dalam pengikatanActionController (yaitu, :postmencari instance var yang disebut @postdi controller Anda.)

method: Nama metode. Ini digunakan untuk menghasilkan nama tag .. Dengan kata lain, atribut objek yang Anda coba dapatkan dari pilih

collection : Koleksi benda

value_method : Untuk setiap objek dalam koleksi, metode ini digunakan untuk nilai

text_method : Untuk setiap objek dalam koleksi, metode ini digunakan untuk teks tampilan

Parameter opsional:

options: Opsi yang dapat Anda lewati. Ini didokumentasikan di sini , di bawah Opsi heading.

html_options: Apa pun yang diteruskan di sini, cukup ditambahkan ke tag html yang dihasilkan. Jika Anda ingin menyediakan kelas, id, atau atribut lainnya, ada di sini.

Asosiasi Anda dapat ditulis sebagai:

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

Berkenaan dengan penggunaan form_for, sekali lagi dalam istilah yang sangat sederhana, untuk semua tag yang datang dalam form_for, misalnya. f.text_field, Anda tidak perlu menyediakan objectparameter pertama ( ). Ini diambil dari form_forsintaks.

zsquare
sumber
2
Terima kasih telah meluangkan waktu ... satu-satunya masalah adalah, sejujurnya, penjelasan Anda tidak membantu menjelaskan hal-hal di kepala saya. Anda menggunakan banyak istilah dalam definisi aktual. Saya menghargai Anda meluangkan waktu - jadi untuk itu, saya memilih itu.
marcamillion
4
Untuk alasan yang dinyatakan dengan jelas oleh marcamillion, saya memilihnya.
Jamie