2011-09-19 60 views
1

有很多类似的主题,但它不帮助我。 有一个帐户模型使用来自窗体中关联模型的数据,Rails 3

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,但实际上我不知道他们需要与否。发生

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

,当我试图箱帐户错误:美元,欧元,卢布

class Currency < ActiveRecord::Base 
    has_many :accounts 
    attr_accessible :id 

    accepts_nested_attributes_for :accounts 
end 

所以在帐户形式我有一个货币选择框 - 即有3个项目的另一个模型货币:

ActiveRecord::AssociationTypeMismatch in AccountsController#create 
Currency(#52889580) expected, got ActiveSupport::HashWithIndifferentAccess(#28841960) 

请求参数:

{"utf8"=>"✓", 
    "authenticity_token"=>"VfCshuGyldoI5Q5DThT/RDpwewCh91apgsnmxyppWqI=", 
    "account"=>{"name"=>"Основной наличный счет", 
    "currency"=>{"id"=>"3"}}, 
    "commit"=>"Save"} 

如果我尝试从标识手动查找货币:

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

回答

3

在你的情况,我认为你是对的,当你质疑accepts_attributes_for的必要性。我认为有一个更简单的方法来实现这一点。

首先,请删除列出的两种型号中的accepts_nested_attributes_for。同时从两个模型中删除attr_accesible,这不是必需的。这实际上是名称未设置的原因,帐户模型只接受货币变量的散列分配。

其次,在您的表单中,您应该使用属性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与选择帮助者一起为你照顾。

总之,当您需要更改关联模型中的某些值或创建/销毁它的实例时,accepts_nested_attributes_for的使用主要是有用的。在你的情况下,你只链接到现有的货币模型而不做任何改变。

+0

非常感谢。此外,我的问题是,帐户有列'货币'没有'_id',所以我加了它,它现在正常工作。 – zishe

+0

很高兴能听到:) – DanneManne

1

除非是嵌套资源,否则您不需要:attr_accessible或:accepched_nested_attributes_for。 attr_accessible is used for mass assignmentaccepts_nested_attributes_for定义了指定关联的属性编写器。

更改select_tag到这样的事情:

<%= f.select(:currency_id, options_from_collection_for_select(Currency.all, :id, :name), :prompt => "Выберите валюту...") %> 
+0

谢谢,它的工作原理。 – zishe