获取fields_for和accepts_nested_attributes_for以使用belongs_to关系

时间:2009-08-21 17:08:41

标签: ruby-on-rails ruby associations nested-attributes

我似乎无法使用Rails 2.3的新belongs_to工具在rails视图中生成accepts_nested_attributes_for关系的嵌套表单。我确实检查了许多可用的资源,看起来我的代码应该正在工作,但是fields_for爆炸了我,我怀疑它与我的如何有关已配置嵌套模型。

我遇到的错误是一个常见错误,可能有很多原因:

'@account[owner]' is not allowed as an instance variable name

以下是涉及的两个模型:

class Account < ActiveRecord::Base
  # Relationships
  belongs_to :owner, :class_name => 'User', :foreign_key => 'owner_id'
  accepts_nested_attributes_for :owner
  has_many :users
end

class User < ActiveRecord::Base
  belongs_to :account
end

也许这就是我在做'rong'的地方,因为帐户可以拥有'所有者',可能有'用户',但用户只有一个'帐户',基于用户模型account_id键。< / p>

这是new.html.haml中的视图代码,它炸毁了我:

- form_for :account, :url => account_path do |account|
  = account.text_field :name
  - account.fields_for :owner do |owner|
    = owner.text_field :name

这是新动作的控制器代码:

class AccountsController < ApplicationController
  # GET /account/new
  def new
    @account  = Account.new
  end
end

当我尝试加载/ account / new时,我得到以下异常:

NameError in Accounts#new
Showing app/views/accounts/new.html.haml where line #63 raised:
@account[owner] is not allowed as an instance variable name

如果我尝试使用神秘的“构建”方法,它只会在控制器中轰炸,也许是因为构建仅适用于多记录关系:

class AccountsController < ApplicationController
  # GET /account/new
  def new
    @account  = Account.new
    @account.owner.build
  end
end

You have a nil object when you didn't expect it!
The error occurred while evaluating nil.build

如果我尝试在控制器中使用@ account.owner_attributes = {}进行设置,或者@ account.owner = User.new,我会回到原始错误,“@account [owner]不允许作为实例变量名称“。

是否还有其他人使用belongs_to关系使用新的accepts_nested_attributes_for方法?你有什么特别或不同的东西吗?所有官方示例和示例代码(如great stuff over at Ryans Scraps)都与多记录关联有关。

4 个答案:

答案 0 :(得分:44)

我已经太晚了几个月,但我正在寻求解决这个错误,而我的情况是我无法将这种关系改为“面对其他方式”。

答案非常简单,你必须在新行动中这样做:

@account.build_owner

表单没有使用fields_for显示的原因是因为它没有有效的对象。你有正确的想法:

@account.owner.build

然而,这不是belongs_to的工作方式。此方法仅使用has_manyhas_and_belongs_to_many生成。

参考: http://guides.rubyonrails.org/association_basics.html#belongs-to-association-reference

答案 1 :(得分:8)

我认为你的accepts_nested_attributes处于错误的关系中。也许这样的事情可行吗?

class Account < ActiveRecord::Base
  belongs_to :owner, :class_name => 'User', :foreign_key => 'owner_id'
  has_many :users
end

class User < ActiveRecord::Base
  belongs_to :account
  has_one :account, :foreign_key => :owner_id
  accepts_nested_attributes_for :account
end

用于构建您要使用build_account的帐户。

您可以在the docs中看到更多示例。

答案 2 :(得分:8)

我正在使用Rails 2.3.5,我注意到了同样的事情。检查active_record的nested_attributes.rb的源代码,看起来belongs_to应该可以正常工作。所以它似乎可能是一个“嵌套表单”错误。

我的嵌套表单与您的完全一样,User belongs_to :addressAddress独立于用户。

然后在表单中,我只是<% f.fields_for :address_attributes do |address_form| %>而不是<% f.fields_for :address do |address_form| %>。临时黑客,直到有更好的方式,但这是有效的。方法accepts_nested_attributes_for期望参数包括:

{user=>{address_attributes=>{attr1=>'one',attr2=>'two'}, name=>'myname'}

...但fields_for正在制作:

{user=>{address=>{attr1=>'one',attr2=>'two'}, name=>'myname'}

这样您就不必将has_one :account添加到您的代码中,这在我的情况下不起作用。

更新:找到更好的答案:

以下是我正在使用的代码的要点:

Rails Nested Forms with belongs_to Gist

希望有所帮助。

答案 3 :(得分:-3)

class Account < ActiveRecord::Base

    belongs_to :owner  :class_name => 'User', :foreign_key => 'owner_id'
end

它对我有用。 :foreign_key =&gt; 'owner_id'是我案例中的关键问题。