Elliot Nelson Elliot Nelson - 1 year ago 128
Ruby Question

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

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

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.

Answer Source

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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download