ruby-on-rails 如何< select>在Rails表单中创建下拉字段?

iqih9akk  于 2022-11-26  发布在  Ruby
关注(0)|答案(9)|浏览(142)

我在做一个脚手架-

rails g scaffold Contact email:string email_provider:string

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

rxztt3cl

rxztt3cl1#

我想显示一个东西(人类可读),但存储另一个东西(整数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
yhqotfr8

yhqotfr82#

您可以查看Rails文档。无论如何,在您的表单中:

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

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

amrnrhlw

amrnrhlw3#

或用于自定义选项

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

ql3eal8s4#

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

对于Rails表单,我还强烈建议您考虑像simple_form -https://github.com/plataformatec/simple_form这样的表单构建器,它将完成所有繁重的工作。

yh2wf1be

yh2wf1be5#

这是一个很长的过程,但是如果你还没有实现,那么你可以用这种方法来创建你的模型。
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)最后,我们需要添加提供者本身。一种方法是使用种子文件:

Provider.destroy_all

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

$ rake db:seed

q5lcpyga

q5lcpyga6#

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

ru9i0ody

ru9i0ody7#

请看这里

  • 您可以使用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>
xmjla07d

xmjla07d8#

使用has_many关联的Rails下拉列表中的文章和类别:

has_many :articles

belongs_to :category

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

64jmpszr9#

在您的模型中,

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的第二个参数将选择任何当前的电子邮件提供商。

相关问题