2011-01-08 17 views
5

Mam model o nazwie appointment. Każdy appointment ma stylist. W postaci gdzie tworzę nową appointment, robię to:Szyny skojarzeń i formularze

<div class="field"> 
    <%= f.label :stylist_id %><br /> 
    <%= f.select(:stylist_id, Stylist.order("name").map { |s| [s.name, s.id] }) %> 
    </div> 

To działa, ale będzie to uciążliwe do tego rodzaju rzeczy dla każdego stowarzyszenia w mojej aplikacji. Wyobrażam sobie, że Rails ma jakiś sposób automatycznego generowania pól wyboru dla skojarzeń, ale nie mam pojęcia, jak to działa. Czy coś takiego istnieje?

Aha, a przy okazji, już wiem o rusztowaniach. Jeśli rusztowanie ma zająć się tym, co opisuję powyżej, najwyraźniej robię coś nie tak, ponieważ to nie robi tego dla mnie.

(jestem na Rails 3.)

+0

Hmmm ... Czy kiedykolwiek uznać za pomocą Formtastic ani żadnego zewnętrznego formularz gem? – Rekin

+0

Prawdopodobnie powinieneś sprawdzić Formtastic dla tego rodzaju zachowania. https://github.com/justinfrench/formtastic –

Odpowiedz

23

Hmm, wydaje się, że collection_select będzie pracować dla typowego scenariusza:

<%= f.collection_select :stylist_id, Stylist.all, :id, :name %> 
1

O ile wiem Szyny nie ma łatwiejszego sposobu tworzenia wybierz tagi. Możesz użyć gem jak formtastic (https://github.com/justinfrench/formtastic) lub simple_form (https://github.com/plataformatec/simple_form), które ułatwiają tworzenie formularzy. Sam wolę simple_form, więc radzę ci wypróbować to.

Innym sposobem jest stworzenie własnego pomocnika wyboru, który automatycznie pobiera powiązane dane z bazy danych. Można również umieścić Stylist.order... rzeczy wewnątrz Model:

# Model 
def self.select 
    Stylist.order("name").map { |s| [s.name, s.id] } 
end 

# Form 
<%= f.select(:stylist_id, Stylist.select) %> 

Sprawia, że ​​widok wyglądają nieco ładniejszy. :)

4

Aż odpowiedź RobinBrouwer jest prawidłowy, po prostu chciałem podzielić się trochę samorodek wymyśliłem dla jednego z naszych aplikacji w pracy:

# config/initializers/to_options.rb 
module ActiveRecord 
    class Base 
    def self.to_options(title=:name) 
     self.all.map{|r| [r.send(title), r.id]} 
    end 
    end 
end 

Teraz można użyć to_options na każdym modelu , z elastycznością wyboru dowolnego pola dla tekstu opcji (domyślnie jest to name).

Model.to_options # => Creates select options with [m.name, m.id] 
AnotherModel.to_options(:title) # => Creates select options with [m.title, m.id] 

Nie powinno być trudno modyfikować przy zamówieniu, jeśli to konieczne.

+0

To z pewnością fajna metoda. Dzięki! :) – RobinBrouwer

Powiązane problemy