Czy ktoś może mi wyjaśnić collection_select w jasnych, prostych słowach?

146

Przeglądam dokumentację Rails API dla collection_selecti są one okropne.

Nagłówek jest taki:

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

A to jedyny przykładowy kod, jaki podają:

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

Czy ktoś może wyjaśnić za pomocą prostego skojarzenia (powiedzmy Userhas_many Plans, a a Plannależy do a User), czego chcę użyć w składni i dlaczego?

Edycja 1: Byłoby wspaniale, gdybyś wyjaśnił, jak to działa w form_helperzwykłym formularzu. Wyobraź sobie, że wyjaśniasz to twórcy stron internetowych, który rozumie tworzenie stron internetowych, ale jest „stosunkowo nowy” w Railsach. Jak byś to wyjaśnił?

marcamillion
źródło
50
Tak. To najbardziej okropna dokumentacja, jaką kiedykolwiek widziałem
Jaseem
1
Aby być uczciwym, dokumentacja jest całkiem w porządku, tylko nie w, FormBuilderale w FormOptionsHelper: api.rubyonrails.org/classes/ActionView/Helpers/ ...
amiuhle
1
Moją ulubioną częścią jest użycie metody collection_select w formularzu, co zmienia cały podpis, tak że obiekt nie jest częścią listy parametrów, ale zamiast tego wywoływana jest metoda collection_select jako metoda obiektu. Nie myśl, że wspominają o tym w dokumentach ...
user3670743
1
To jest projekt open source: jeśli dokumentacja jest słaba, możemy winić tylko siebie; mogłoby to być niesamowite, gdybyśmy tylko zrobili co w naszej mocy, aby było lepiej. Małe / proste PR mogą przejść długą drogę.
BKSpurgeon

Odpowiedzi:

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

Lub Twój przykład może być przedstawiony jako następujący kod:

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

Nie jest to udokumentowane w FormBuilder, ale wFormOptionsHelper

alexkv
źródło
32
To jest jedno z najlepszych wyjaśnień złożonej struktury Railsów, jakie widziałem. Użyłeś przejrzystego języka wraz z podstawowymi konstrukcjami Railsów, aby go utrwalić. Dzięki wielkie!!
marcamillion
2
Dlaczego miałbyś kiedykolwiek nazwać to „post [identyfikator_autora]”?
Jaseem
@alexkv dziękuję - czy byłbyś w stanie rozwinąć znaczenie: post, # przestrzeń nazw pól i: author_id, # parametry nazwy pola (pierwsze dwa) - nie rozumiem ich celu w schemacie rzeczy - potrafię ' t zostały pominięte?
BKSpurgeon
1
Pierwszy parametr może rzeczywiście mieć wartość zero. Jeśli tworzysz formę obiektu, będzie to ten obiekt, więc zaznaczenie będzie miało taką samą przestrzeń nazw, jak reszta formularza. Jeśli to nie jest potrzebne, zostaw 1 jako zero. Drugi to nazwa kontrolki, więc jeśli ma aktualizować pole w obiekcie (pierwszy parametr), to nazwa pola jest drugim parametrem. Jeśli tworzysz jakiś formularz do innych zastosowań, drugi parametr jest tym, co chcesz, aby formant formularza miał nazwę i identyfikator. Dlaczego używać tego z nil 1st? Prawdopodobnie dlatego, że chcesz collection_select dla opcji: prompt.
elc
1
Powinienem również zauważyć, że ten sam efekt można uzyskać, dołączając parametr zachęty do select_tag, który używa options_for_select, co prawdopodobnie odpowiadałoby tak samo, jak collection_select z obiektem nil.
elc
21

Sam spędziłem trochę czasu nad permutacjami wybranych tagów.

collection_selecttworzy znacznik wyboru z kolekcji obiektów. Mając to na uwadze,

object: Nazwa obiektu. Służy do generowania nazwy tagu i służy do generowania wybranej wartości. Może to być rzeczywisty obiekt lub symbol - w tym drugim przypadku zmienna instancji o tej nazwie jest wyszukiwana w powiązaniu elementuActionController (to znaczy :postszuka instancji var wywołanej @postw kontrolerze).

method: Nazwa metody. Służy do generowania nazwy tagu. Innymi słowy, atrybut obiektu, który próbujesz uzyskać z zaznaczenia

collection : Zbiór obiektów

value_method : Dla każdego obiektu w kolekcji ta metoda jest używana jako wartość

text_method : Ta metoda jest używana do wyświetlania tekstu dla każdego obiektu w kolekcji

Parametry opcjonalne:

options: Opcje, które możesz przejść. Są one udokumentowane tutaj , pod nagłówkiem Opcje.

html_options: Cokolwiek jest tu przekazywane, jest po prostu dodawane do wygenerowanego tagu html. Jeśli chcesz podać klasę, identyfikator lub inny atrybut, przejdź tutaj.

Twoje skojarzenie można zapisać jako:

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

Jeśli chodzi o używanie form_for, znowu w bardzo prosty sposób, dla wszystkich tagów, które znajdują się w form_for, np. f.text_field, nie musisz podawać pierwszego objectparametru ( ). Jest to zaczerpnięte ze form_forskładni.

zsquare
źródło
2
Dzięki za poświęcenie czasu ... jedynym problemem jest to, że szczerze mówiąc, twoje wyjaśnienie nie pomaga wyjaśnić rzeczy w mojej głowie. Użyłeś wielu terminów w rzeczywistej definicji. Doceniam jednak, że poświęciłeś czas - więc w związku z tym zagłosowałem.
marcamillion
4
Z powodów tak jasno określonych przez marcamillion, przegłosowałem to.
Jamie