让 fields_for 和accepts_nested_attributes_for 处理belongs_to 关系
-
19-09-2019 - |
题
我似乎无法在 Rails 视图中生成嵌套表单 belongs_to
使用新的关系 accepts_nested_attributes_for
Rails 2.3 的设施。我确实检查了许多可用的资源,它看起来像我的代码 应该 正在工作,但是 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
也许这就是我做“错误”的地方,因为一个帐户可以有一个“所有者”,也可以有“用户”,但根据用户模型 account_id 键,用户只有一个“帐户”。
这是 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] 不允许作为实例”变量名”。
还有其他人有新的 Accept_nested_attributes_for 方法来处理 Israel 关系吗?你有什么特别的或不同的事情要做吗?所有官方示例和示例代码(例如 Ryans Scraps 的好东西) 涉及多记录关联。
解决方案
我认为你的 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 的帐户。
您可以在以下位置查看更多示例 文档.
其他提示
我晚了几个月,但我一直在寻求解决这个错误,而我的情况是我无法改变这种关系以“面向另一个方向”。
答案确实很简单,您必须在新操作中执行此操作:
@account.build_owner
使用 fields_for 表单未显示的原因是它没有有效的对象。你的想法是正确的:
@account.owner.build
然而,这不是办法 belongs_to
工作。此方法仅生成 has_many
和 has_and_belongs_to_many
.
参考:http://guides.rubyonrails.org/association_basics.html#belongs-to-association-reference
我正在使用 Rails 2.3.5,我注意到了同样的事情。查看active_record的nested_attributes.rb的源代码,看起来belongs_to应该可以正常工作。所以看来这可能是一个“嵌套表单”错误。
我有一个与你的完全一样的嵌套形式 User belongs_to :address
, , 和 Address
独立于用户。
然后在表格中,我只是做 <% 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
到你的代码,这在我的情况下不起作用。
更新:找到了更好的答案:
这是我用来使这项工作正常进行的代码要点:
希望有帮助。
class Account < ActiveRecord::Base
belongs_to :owner :class_name => 'User', :foreign_key => 'owner_id'
end
这个对我有用。:foreign_key => 'owner_id' 是我案例中的关键问题。