新手问题 请教 inverse_of 的作用

346617552 · 2012年10月31日 · 最后由 xworm 回复于 2016年06月17日 · 4952 次阅读
class Topic < ActiveRecord::Base
  belongs_to :user, :counter_cache => true, :inverse_of => :topics
  ...
end

Ruby-Doc: If you are using a belongs_to on the join model, it is a good idea to set the :inverse_of option on the belongs_to, which will mean that the following example works correctly (where tags is a has_many :through association):

@post = Post.first
@tag = @post.tags.build :name => "ruby"
@tag.save

The last line ought to save the through record (a Taggable). This will only work if the :inverse_of is set:

class Taggable < ActiveRecord::Base
  belongs_to :post
  belongs_to :tag, :inverse_of => :taggings
end

还是不太明白。。。

今天就遇到了这个

class Agreement < ActiveRecord::Base
  has_many :fees
end

class Fee < ActiveRecord::Base
  belongs_to :agreement

  validates_presence_of :target_id, :unless => proc{|fee| fee.agreement.try(:step) == 'choose_services' }
  validates_presence_of :price
end

# in controller
@agremeent = Agreement.new
@agreement.step = "choose_services"
@agreement.fees.build :price => 1

@agreement.valid?

这个时候得出的结果 是false,因为 agreement还没有持久化,在Model Fee里的验证中 "fee.agreement.try(:step) " 返回的是空 因为 fee.agreement是nil。 (没有持久化的关联对象的形成比较复杂。)
那么这个验证的结果就出错了

加上inverse_of

class Agreement < ActiveRecord::Base
  has_many :fees, :inverse_of => :agreement
end

再执行以上代码,
@agreement.valid? 返回 true

懂了吗?

IChou 关于 inverse_of 的困惑与探究 提及了此话题。 06月17日 11:52
需要 登录 后方可回复, 如果你还没有账号请 注册新账号