Як створити випадаюче поле <select> у формі рейок?


78

Я створюю риштування -

rails g scaffold Contact email:string email_provider:string 

але я хочу, щоб постачальник послуг електронної пошти був випадаючим (із опціями gmail / yahoo / msn), а не текстовим полем. Як я можу це зробити?

Відповіді:


89

Ви можете поглянути на документацію Rails . У будь-якому випадку, у вашій формі:

  <%= f.collection_select :provider_id, Provider.order(:name),:id,:name, include_blank: true %>

Як ви можете здогадатися, вам слід Providerвизначити постачальників послуг електронної пошти в іншій моделі - , щоб мати де їх вибрати.


отже, модель буде contact.rb, але куди мені покласти цю логіку випадаючого списку? вибачте за наївне запитання, я новачок у розробці RoR
iCyborg

1
Ваше запитання нормальне. Якщо ви подивитесь на структуру вашого app/views/contacts, ви знайдете файл _form.html.erb. Ви можете спробувати розмістити його там. Цей "частковий вигляд" відповідає як за створення, так і за оновлення дій створеного вами ешафоту.
Р Мілушев

3
рекомендуємо перемістити замовлення (: назва) до області (яка є методом) у моделі. Тут це не велика справа, але з часом ви виявите, що наявність такого, що є, по суті, діловою логікою, як це (замовлення) на шаблоні подання, стає безладом. Перемістіть його на контролер, або в ідеалі модель, і зробіть там доступну область, яку ви можете використовувати. Один приклад - якщо у вас вийде три екрани або шаблони, які використовують спадне меню, порядок у поданнях означає дублювання 3 X. Наявність його в моделі означає, що воно визначене в одному місці, і це єдине місце, щоб змінити його, що є добре.
Michael Durrant

53

Або для нестандартних параметрів

<%= f.select :desired_attribute, ['option1', 'option2']%>

6
<% = f.select: бажаний_атрибут, options_for_select ([['opt1'], ['opt2']]) Це працює для мене
longJOURNEY

16

Ви створюєте колекцію в Contactконтролері -

app/controllers/contacts_controller.erb 

Додавання

@providers = Provider.all.by_name

до нових, створюйте та редагуйте методи, використовуючи область для by_nameв Providerмоделі - app/models/provider.rb- для впорядкування за іменем

scope by_name  order(:name)

Тоді в поданні - app/views/contacts/_form.html.erb- ви використовуєте

<%= f.collection_select :provider_id, @providers, :id, :name, include_blank: true %>

Що стосується форм рейок, я також настійно рекомендую вам поглянути на конструктор форм, такий як simple_form - https://github.com/plataformatec/simple_form - який зробить усі важкі роботи.


Дякую, Майкл, я відредагував запитання і поставив інший код, який працював для мене, так що просто цікаво, в чому різниця у використанні Select і collection_select, як зазначено нижче у відповідях?
iCyborg

9

Це довгий шлях, але якщо ви ще не впровадили його, ви можете спочатку створити свої моделі таким чином. Метод нижче описує зміну існуючої бази даних.

1) Створіть нову модель для постачальників послуг електронної пошти:
$ rails g model provider name

2) Це створить вашу модель із рядком імені та позначками часу. Він також створює міграцію, яку нам потрібно додати до схеми за допомогою:
$ rake db:migrate

3) Додайте міграцію, щоб додати ідентифікатор постачальника до контакту:
$ rails g migration AddProviderRefToContacts provider:references

4) Перейдіть до файлу міграції, щоб перевірити, чи виглядає він нормально, і перенесіть і це:
$ rake db:migrate

5) Гаразд, тепер у нас є ідентифікатор провайдера, нам більше не потрібен оригінальний рядок електронної_провайдера:
$ rails g migration RemoveEmailProviderFromContacts

6) Всередині файлу міграції додайте зміну, яка виглядатиме приблизно так:

class RemoveEmailProviderFromContacts < ActiveRecord::Migration
  def change
    remove_column :contacts, :email_provider
  end
end

7) Після цього перенесіть зміни:
$ rake db:migrate

8) Візьмемо цей момент, щоб оновити наші моделі:
Контакт: belongs_to :provider
Постачальник:has_many :contacts

9) Потім ми встановлюємо логіку випадаючого списку в частковому _form.html.erb у поданнях:

  <div class="field">
    <%= f.label :provider %><br>
    <%= f.collection_select :provider_id, Provider.all, :id, :name %>
  </div>

10) Нарешті, нам потрібно додати самі постачальники. Одним із найкращих способів буде використання насіннєвого файлу:

Provider.destroy_all

gmail = Provider.create!(name: "gmail")
yahoo = Provider.create!(name: "yahoo")
msn = Provider.create!(name: "msn")

$ rake db:seed



5

Будь ласка, подивіться тут

Або ви можете використовувати тег rails, або використовувати звичайні теги HTML

Бірка рейок

<%= select("Contact", "email_provider", Contact::PROVIDERS, {:include_blank => true}) %>

* верхній рядок коду стане HTML-кодом (HTML-тегом), знайдіть його нижче *

Тег HTML

<select name="Contact[email_provider]">
  <option></option>
  <option>yahoo</option>
  <option>gmail</option>
  <option>msn</option>
</select>

дякую, я все ще в розгубленості, я розумію, що код <select> буде розміщений у _form.html.erb, але куди піде код вибору ("Контакт",)?
iCyborg

3

У вашій моделі

class Contact
  self.email_providers = %w[Gmail Yahoo MSN]
  validates :email_provider, :inclusion => email_providers
end

У вашій формі

<%= f.select :email_provider, 
    options_for_select(Contact.email_providers, @contact.email_provider) %>

у другому аргументі options_for_select буде вибрано будь-який поточний постачальник_ електронної пошти.


2

Спадаючі рейки за допомогою асоціації has_many для статті та категорії:

has_many :articles

belongs_to :category

<%= form.select :category_id,Category.all.pluck(:name,:id),{prompt:'select'},{class: "form-control"}%>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.