简体   繁体   中英

Two models accept nested attributes for each other, generate stack level too deep

I'm wondering if I'm only the one with this issue. To pinpoint it, I have created two very basic models.

# user.rb
class User < ActiveRecord::Base
  has_one :role, :inverse_of => :user
  accepts_nested_attributes_for :role
end

# role.rb
class Role < ActiveRecord::Base
  belongs_to :user, :inverse_of => :role
  accepts_nested_attributes_for :user
end

In the rails console, attempting to update a simple attribute of the Role class fails if the User model has been loaded .

Loading development environment (Rails 3.2.2)
1.9.3-p194 :001 > Role.first.update_attribute(:role_type, 72)
 => true 
1.9.3-p194 :002 > Role.first.tap {|r| r.user}.update_attribute(:role_type, 72)
SystemStackError: stack level too deep
    from /Users/enelson/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb/workspace.rb:80
Maybe IRB bug!

If I remove either one of the accepts_nested_attributes directives, this problem goes away. I guess the easy answer here is "well then, why don't you get rid of one of them?" The problem is that would involve rewriting a lot of existing pages in an application, and if there's a different fix or workaround, I'd like to hear about it.

Design-wise, it's not correct composition that Role "has a" User. It may be better to correct the design at this stage, rather than leave it.

Both relationships are also defined as "inverse of" the other; that might also possibly be contributing to the infinite recursion.

I had the same issue, found this: https://github.com/rails/rails/issues/7809 and then this pull request https://github.com/rails/rails/pull/7824 . Added it as monkeypatch to project, hope it won't introduce any nasty bugs.

根据文档 ,您应该从Role模型中删除accetps_nested_attributes_for ,并保留inverse_of

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM