【问题标题】:Rails has_many, build, inverse_ofRails has_many, build, inverse_of
【发布时间】:2011-04-19 03:48:53
【问题描述】:

我有 2 个这样的模型:

class User < ActiveRecord::Base
    has_many :user_services, :inverse_of => :user

    validates_length_of :user_services, :maximum => 3
end

class UserService < ActiveRecord::Base
    belongs_to :user, :inverse_of => :user_services

    validates_associated :user
end

我想做这样的事情:

user_service = user.user_services.build(...)
if user_service.save
...

但它会引发“堆栈级别太深”错误。我假设是因为 validates_associated 与 inverse_of 相结合。有谁知道为什么会这样?

直接在用户对象而不是 user_service 对象上调用 save 似乎可行,但我想知道是否有办法反过来实现这些。

谢谢!

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 activerecord associations has-many


    【解决方案1】:

    发生这种情况是因为您的验证具有循环依赖关系。

    validates_length_of :user_services
    validates_associated :user
    

    http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#method-i-validates_associated

    更新

    如果你用这种方式重写你的代码,你可以移除循环依赖:

    class User < ActiveRecord::Base
      has_many :user_services, :inverse_of => :user
      validates_length_of :user_services, :maximum => 3
    end
    
    class UserService < ActiveRecord::Base
      belongs_to :user, :inverse_of => :user_services
    
      def user_services_amount
         return 0 if self.user.nil?
         self.user.user_services.length
      end
    
      validates :user_services_amount, :inclusion => { :in => 0..3 }
    end
    

    【讨论】:

    • 谢谢!是的,这似乎与我发现的这个问题有关:rails.lighthouseapp.com/projects/8994/tickets/…
    • 添加此循环问题的解决方案
    • 很好的解决方案。但看起来需要删除幻数重构:您可以使用User.max_services_allowed 方法将幻数3 移出所有检查。
    • 感谢您的跟进!效果很好。
    • 可能与这些问题有关:7809, 16640
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-04
    • 1970-01-01
    相关资源
    最近更新 更多