如何有一个下拉 < 选择 > 字段在轨道形式?

我正在创建一个脚手架-

rails g scaffold Contact email:string email_provider:string

但我希望电子邮件提供商是一个下拉列表(与 gmail/yahoo/msn 作为选项) ,而不是一个文本字段。我怎么能这么做?

205964 次浏览

请看一下 给你

可以使用 Rails 标记,也可以使用纯 HTML 标记

Rails 标签

<%= 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>

你可以看看 Rails 文档。无论如何,在你的形式:

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

正如您所猜测的,您应该在另一个模型 -Provider中预先定义电子邮件提供者,以便从中选择它们。

Contact控制器中创建集合-

app/controllers/contacts_controller.erb

添加

@providers = Provider.all.by_name

使用 Provider模型中 by_name的作用域(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 %>

对于 Rail 表单,我还强烈建议您查看诸如 simple _ form-https://github.com/plataformatec/simple_form之类的表单生成器,它将完成所有繁重的工作。

在你的模型里,

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 的第二个参数将选择任何当前的 email _ Provider。

或者自定义选项

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

这还有很长的路要走,但是如果您还没有实现,那么您最初可以这样创建模型。下面的方法描述如何更改现有数据库。

1)为电邮服务供应商建立新模式:
$ rails g model provider name

2)这将创建带有名称字符串和时间戳的模型。它还创建了我们需要添加到模式的迁移:
$ rake db:migrate

3)添加一个迁移,将提供商 ID 添加到联系人:
$ rails g migration AddProviderRefToContacts provider:references

4)检查迁移文件看起来是否正常,然后也进行迁移:
$ rake db:migrate

5)好的,现在我们已经有了 Provider _ id,我们不再需要原始的 email _ Provider 字符串:
$ 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)最后,我们需要添加提供者本身。Top 做到这一点的一个方法是使用种子文件:

Provider.destroy_all


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

$ rake db:seed

<%= f.select :email_provider, ["gmail","yahoo","msn"]%>

Rails 下拉菜单,使用 has _ many 关联的文章和类别:

has_many :articles


belongs_to :category


<%= form.select :category_id,Category.all.pluck(:name,:id),{prompt:'select'},{class: "form-control"}%>

我想显示一样东西(人类可读) ,但存储另一样东西(一个整数 id)。

举个小例子

下面是一个有帮助的小例子:

<%= form.select(:attribute_name, {cat: 5, dog: 3} )%>

{cat: 5, dog: 3}将显示“猫”和“狗”,但保存5和3。


真实世界的例子

下面是实际的用例。它显示了卖家的名字(人们可以读懂) ,但是保存了卖家的 id (一个整数) :

<div class="field">
<%= form.label :seller_id %>
<%= form.select :seller_id, seller_names_and_ids(), {include_blank: true}, {required: true, class: "form-control"} %>
</div>

助手的定义是:

def seller_names_and_ids
# We want this to produce a hash of keys (the thing to display) and values (the thing to save,
# in thise case the seller_id integer)
sellers = Seller.all
h = {}
sellers.each do |seller|
thing_to_display = seller.name + " (" + seller.id.to_s + ")"
thing_to_save_in_db = seller.id
h.store(thing_to_display, thing_to_save_in_db)
end
h
end