有很多类似的主题,但它对我没有帮助。 有一个帐户模型
class Account < ActiveRecord::Base
belongs_to :user
belongs_to :currency
attr_accessible :currency
accepts_nested_attributes_for :currency
end
我添加了attr_accessible和accepts_nested_attributes_for,但实际上我不知道他们是否需要。另一种型号货币有3个项目 - 美元,欧元,RUR
class Currency < ActiveRecord::Base
has_many :accounts
attr_accessible :id
accepts_nested_attributes_for :accounts
end
因此,在帐户表单中,我有一个带货币的选择框:
<%= form_for @account do |f| %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :currency %><br />
<%= select_tag(:currency, options_from_collection_for_select(Currency.all, :id, :name),\
:id => "account_currency_id", :name => "account[currency][id]", :prompt => "Выберите валюту...")%>
</div>
<div class="actions">
<%= f.submit "Сохранить" %>
</div>
<% end %>
当我试图创建帐户错误时:
ActiveRecord::AssociationTypeMismatch in AccountsController#create
Currency(#52889580) expected, got ActiveSupport::HashWithIndifferentAccess(#28841960)
请求参数:
{"utf8"=>"✓",
"authenticity_token"=>"VfCshuGyldoI5Q5DThT/RDpwewCh91apgsnmxyppWqI=",
"account"=>{"name"=>"Основной наличный счет",
"currency"=>{"id"=>"3"}},
"commit"=>"Save"}
如果我尝试手动从Id中找到货币:
param = params[:account]
param[:currency] = Currency.find(param[:currency][:id])
@account = Account.new(param)
女巫姓名不存在新错误。而且我不喜欢我应该手动设置:id => "account_currency_id", :name => "account[currency][id]"
,因为默认情况下它们都是“货币”。
Rails 3.1
答案 0 :(得分:3)
在你的情况下,当你质疑accepts_attributes_for
的必要性时,我认为你是对的。我认为有一种更容易实现的目的。
首先,删除您列出的两个模型中的accepts_nested_attributes_for
。同时从两个模型中删除attr_accesible
,不需要它。这实际上是未设置名称的原因,Account模型只接受货币变量的哈希分配。
其次,在您的表单中,您应该使用属性currency_id
而不是currency[id]
。这样你就不必经历另一个模型。我将如何做到这一点:
<%= f.select(:currency_id,
options_from_collection_for_select(Currency.all, :id, :name),
:prompt => "Выберите валюту...") %>
请注意,我已从select_tag
更改为f.select
。这样您就不需要手动指定:id或:name。 form_for与select helper结合使用将为您解决这个问题。
总而言之,当您需要更改关联模型中的某些值或创建/销毁它的实例时,accepts_nested_attributes_for
的使用主要是有用的。在您的情况下,您只链接到现有货币模型而不对其进行任何更改。
答案 1 :(得分:1)
您不需要:attr_accessible或:accepts_nested_attributes_for,除非它是嵌套资源。 attr_accessible is used for mass assignment和accepts_nested_attributes_for定义了指定关联的属性编写器。
将select_tag更改为以下内容:
<%= f.select(:currency_id, options_from_collection_for_select(Currency.all, :id, :name), :prompt => "Выберите валюту...") %>