Kann mir jemand collection_select in klaren, einfachen Worten erklären?

146

Ich gehe die Rails API-Dokumente durch collection_selectund sie sind schrecklich.

Die Überschrift lautet:

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

Und dies ist der einzige Beispielcode, den sie geben:

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

Kann jemand anhand einer einfachen Zuordnung (z. B. Userhas_many Plansund a Plangehört zu a User) erklären, was ich in der Syntax verwenden möchte und warum?

Bearbeiten 1: Außerdem wäre es fantastisch, wenn Sie erklären würden, wie es in einer form_helperoder einer regulären Form funktioniert . Stellen Sie sich vor, Sie erklären dies einem Webentwickler, der die Webentwicklung versteht, für Rails jedoch "relativ neu" ist. Wie würden Sie es erklären?

Marcamillion
quelle
50
Ja. Das ist die schrecklichste Dokumentation, die ich je gesehen habe
Jaseem
1
Um fair zu sein, die Dokumentation ist ganz FormBuilderin Ordnung , nur nicht in der, sondern in der FormOptionsHelper: api.rubyonrails.org/classes/ActionView/Helpers/…
amiuhle
1
Mein Lieblingsteil ist, wenn Sie collection_select in einem Formular verwenden und dadurch die gesamte Signatur so geändert wird, dass das Objekt nicht Teil der Parameterliste ist, sondern collection_select als Methode für das Objekt aufgerufen wird. Denken Sie nicht, dass sie das in den Dokumenten erwähnen ...
user3670743
1
Dies ist ein Open-Source-Projekt: Wenn die Dokumentation schlecht ist, sind wir selbst schuld; Es könnte erstaunlich sein, wenn wir nur unseren Beitrag dazu leisten würden, es besser zu machen. Kleine / einfache PRs machen einen langen Weg.
BKSpurgeon

Antworten:

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

Oder Ihr Beispiel kann wie folgt dargestellt werden:

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

Dies ist nicht in der FormBuilder, sondern in der dokumentiertFormOptionsHelper

alexkv
quelle
32
Dies ist leicht eine der besten Erklärungen für eine komplexe Rails-Struktur, die ich gesehen habe. Sie haben eine klare Sprache zusammen mit grundlegenden Rails-Konstrukten verwendet, um sie zu verfestigen. Vielen Dank!!
Marcamillion
2
Warum würden Sie es jemals "post [author_id]" nennen?
Jaseem
@alexkv danke - könnten Sie die Bedeutung der Parameter: post, # field namespace und: author_id, # field name (die ersten beiden) näher erläutern - ich verstehe ihren Zweck im Schema der Dinge nicht - can ' t sie weggelassen werden?
BKSpurgeon
1
Der erste Parameter kann tatsächlich Null sein. Wenn Sie ein Objektformular erstellen, handelt es sich um dieses Objekt, sodass die Auswahl denselben Namensraum wie der Rest des Formulars hat. Wenn das nicht benötigt wird, lassen Sie 1. als Null. Der zweite ist der Name des Steuerelements. Wenn also ein Feld für ein Objekt aktualisiert werden soll (1. Parameter), ist der Feldname der zweite Parameter. Wenn Sie ein Formular für andere Zwecke erstellen, ist der zweite Parameter der Name und die ID des Formularsteuerelements. Warum dies mit Null 1 verwenden? Wahrscheinlich, weil Sie collection_select für die Eingabeaufforderungsoptionen möchten.
Elc
1
Ich sollte auch beachten, dass Sie den gleichen Effekt erzielen können, wenn Sie einen Eingabeaufforderungsparameter an einen select_tag anheften, der options_for_select verwendet. Dies würde wahrscheinlich genauso antworten wie ein collection_select mit einem Null-Objekt.
Elc
21

Ich habe selbst einige Zeit mit den Permutationen der ausgewählten Tags verbracht.

collection_selectErstellt ein Select-Tag aus einer Sammlung von Objekten. Denken Sie daran,

object: Name des Objekts. Dies wird verwendet, um den Namen des Tags zu generieren, und wird verwendet, um den ausgewählten Wert zu generieren. Dies kann ein tatsächliches Objekt oder ein Symbol sein. Im letzteren Fall wird die Instanzvariable dieses Namens in der Bindung derActionController (dh :postsucht nach einer aufgerufenen Instanzvariablen) gesucht@post in Ihrem Controller wird.).

method: Name der Methode. Dies wird verwendet, um den Namen des Tags zu generieren. Mit anderen Worten, das Attribut des Objekts, das Sie aus der Auswahl abrufen möchten

collection : Die Sammlung von Objekten

value_method : Für jedes Objekt in der Auflistung wird diese Methode als Wert verwendet

text_method : Für jedes Objekt in der Sammlung wird diese Methode zum Anzeigen von Text verwendet

Optionale Parameter:

options: Optionen, die Sie übergeben können. Diese sind hier dokumentiert unter der Überschrift Optionen .

html_options: Was auch immer hier übergeben wird, wird einfach zum generierten HTML-Tag hinzugefügt. Wenn Sie eine Klasse, eine ID oder ein anderes Attribut angeben möchten, klicken Sie hier.

Ihr Verein könnte geschrieben werden als:

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

In Bezug auf die Verwendung form_foraller Tags, die in die form_forz. f.text_fieldmüssen Sie den objectParameter first ( ) nicht angeben. Dies ist der form_forSyntax entnommen .

zsquare
quelle
2
Vielen Dank, dass Sie sich die Zeit genommen haben. Das einzige Problem ist jedoch, dass Ihre Erklärung ehrlich gesagt nicht dazu beiträgt, die Dinge in meinem Kopf zu klären. Sie haben viele der Begriffe in der eigentlichen Definition verwendet. Ich weiß es zu schätzen, dass Sie sich die Zeit genommen haben - deshalb habe ich dafür gestimmt.
Marcamillion
4
Aus den von marcamillion so klar genannten Gründen habe ich es abgelehnt.
Jamie