Ruby-on-rails 获取 fields_for 和 accepts_nested_attributes_for 以处理belongs_to 关系
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1313149/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting fields_for and accepts_nested_attributes_for to work with a belongs_to relationship
提问by Billy Gray
I cannot seem to get a nested form to generate in a rails view for a belongs_torelationship using the new accepts_nested_attributes_forfacility of Rails 2.3. I did check out many of the resources available and it looks like my code shouldbe working, but fields_forexplodes on me, and I suspect that it has something to do with how I have the nested models configured.
我似乎无法belongs_to使用accepts_nested_attributes_forRails 2.3的新工具在 Rails视图中为关系生成嵌套表单。我确实检查了许多可用的资源,看起来我的代码应该可以正常工作,但fields_for对我来说是爆炸性的,我怀疑这与我如何配置嵌套模型有关。
The error I hit is a common one that can have many causes:
我遇到的错误是一个常见的错误,可能有很多原因:
'@account[owner]' is not allowed as an instance variable name
Here are the two models involved:
以下是涉及的两个模型:
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
Perhaps this is where I am doing it 'rong', as an Account can have an 'owner', and may 'users', but a user only has one 'account', based on the user model account_id key.
也许这就是我在做“荣”的地方,因为一个帐户可以有一个“所有者”,也可能有一个“用户”,但根据用户模型 account_id 键,一个用户只有一个“帐户”。
This is the view code in new.html.haml that blows up on me:
这是 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
And this is the controller code for the new action:
这是新操作的控制器代码:
class AccountsController < ApplicationController
# GET /account/new
def new
@account = Account.new
end
end
When I try to load /account/new I get the following exception:
当我尝试加载 /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
If I try to use the mysterious 'build' method, it just bombs out in the controller, perhaps because build is just for multi-record relationships:
如果我尝试使用神秘的“构建”方法,它只会在控制器中爆炸,也许是因为构建仅用于多记录关系:
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
If I try to set this up using @account.owner_attributes = {} in the controller, or @account.owner = User.new, I'm back to the original error, "@account[owner] is not allowed as an instance variable name".
如果我尝试在控制器中使用@account.owner_attributes = {} 或@account.owner = User.new 进行设置,我将回到原来的错误,“@account[owner] 不允许作为实例变量名”。
Does anybody else have the new accepts_nested_attributes_for method working with a belongs_to relationship? Is there something special or different you have to do? All the official examples and sample code (like the great stuff over at Ryans Scraps) is concerned with multi-record associations.
有没有其他人使用新的accepts_nested_attributes_for 方法处理belongs_to 关系?你有什么特别或不同的事情要做吗?所有官方示例和示例代码(如Ryans Scraps 上的精彩内容)都与多记录关联有关。
采纳答案by Andy Gaskell
I think your accepts_nested_attributesis on the wrong side of the relationship. Maybe something like this would work?
我认为你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
For building the account you want to use build_account.
要建立您要使用 build_account 的帐户。
You can see more examples in the docs.
您可以在文档中看到更多示例。
回答by Jaryl
I'm a few months too late, but I was looking to solve this error and my situation was that I could not change the relationship to 'face the other way'.
我已经晚了几个月,但我正在寻求解决这个错误,我的情况是我无法将关系改变为“面对其他方式”。
The answer really is quite simple, you have to do this in your new action:
答案真的很简单,你必须在你的新动作中做到这一点:
@account.build_owner
The reason why the form did not display using fields_for was because it did not have a valid object. You had the right idea up there with:
表单没有使用 fields_for 显示的原因是因为它没有有效的对象。你有正确的想法:
@account.owner.build
However, this is not the way belongs_towork. This method is only generated with has_manyand has_and_belongs_to_many.
然而,这不是belongs_to工作方式。此方法仅使用has_many和生成has_and_belongs_to_many。
Reference: http://guides.rubyonrails.org/association_basics.html#belongs-to-association-reference
参考:http: //guides.rubyonrails.org/association_basics.html#belongs-to-association-reference
回答by Lance Pollard
I'm using Rails 2.3.5 and I noticed the same thing. Checking out the source for active_record's nested_attributes.rb, it looks like belongs_to should work fine. So it appears it might be a "nested forms" bug.
我正在使用 Rails 2.3.5,我注意到了同样的事情。查看active_record 的nested_attributes.rb 的源代码,看起来belongs_to 应该可以正常工作。所以看起来它可能是一个“嵌套表单”错误。
I have a nested form exactly like yours, with User belongs_to :address, and Addressis independent of the user.
我有一个与您完全一样的嵌套表单,带有User belongs_to :address, 并且Address独立于用户。
Then in the form, I just do <% f.fields_for :address_attributes do |address_form| %>instead of <% f.fields_for :address do |address_form| %>. Temporary hack until there's a better way, but this works. The method accepts_nested_attributes_foris expecting the params to include something like:
然后在表单中,我只是执行<% 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'}
{user=>{address_attributes=>{attr1=>'one',attr2=>'two'}, name=>'myname'}
...but fields_foris producing:
...但fields_for正在生产:
{user=>{address=>{attr1=>'one',attr2=>'two'}, name=>'myname'}
{user=>{address=>{attr1=>'one',attr2=>'two'}, name=>'myname'}
This way you don't have to add that has_one :accountto your code, which doesn't work in my case.
这样您就不必将其添加has_one :account到您的代码中,这在我的情况下不起作用。
Update: Found a better answer:
更新:找到了更好的答案:
Here is the gist of the code I'm using to make this work right:
这是我用来使这项工作正常进行的代码的要点:
Rails Nested Forms with belongs_to Gist
Hope that helps.
希望有帮助。
回答by Zdenek.paclik
class Account < ActiveRecord::Base
belongs_to :owner :class_name => 'User', :foreign_key => 'owner_id'
end
It works for me. :foreign_key => 'owner_id' was the key problem in my case.
这个对我有用。:foreign_key => 'owner_id' 是我的关键问题。

