我认为我可以使用before_remove回调来做到这一点,但由于某种原因,这不是解雇,我不明白为什么.
class Person < ActiveRecord::Base has_many :limbs,before_remove: :print_message def print_message puts 'removing a limb' end end class Limb < ActiveRecord::Base belongs_to :person end
虽然这个代码应该在肢体破坏期间打印“移除肢体”,但事实并非如此.
p = Person.create; l = Limb.create person: p; p.limbs.first.destroy # sql (2.1ms) DELETE FROM "limbs" WHERE "limbs"."id" = ? [["id",5]] # => #<Limb id: 5,person_id: 3,created_at: "2012-01-17 11:28:01",updated_at: "2012-01-17 11:28:01">
为什么这会破坏操作不会导致print_message方法运行?
编辑 – 这是否存在before_remove回调?
许多人都在询问是否存在此回调.虽然我可以找到很少的进一步引用,但它在Rails文档中有记录:
它是一个关联回调,而不是根ActiveRecord回调
编辑2 – 为什么不在limb上使用before_destroy?
有些人问为什么我没有在Limb上使用before_destroy回调.原因是我希望人检查是否有最小数量的肢体,并且最后一个肢体永远不会被摧毁.这是原始问题:
How do you ensure that has_many always “has a minimum”?
解决方法
这是你如何使用它:
class Person < ActiveRecord::Base has_many :limbs,:before_remove => :print_message def print_message(limb) # limb variable references to a Limb instance you're removing # ( do some action here ) # ... end end class Limb < ActiveRecord::Base belongs_to :person end
p = Person.create l = Limb.create(:person => p) p.limbs.first.destroy
在这里你在Limb实例上调用它,这就是为什么没有触发的原因.
在您创建的关联上调用它:
p = Person.create l = Limb.create(:person => p) p.limbs.destroy(l)
编辑
为了保留最少的关联对象,您可以执行以下操作:
class Person < ActiveRecord::Base has_many :limbs,:before_remove => :preserve_mimimum def preserve_minimum(limb) raise "Minimum must be preserved" if limbs.count == 1 end end class Limb < ActiveRecord::Base belongs_to :person end
然而,这不会在p.limbs.destroy_all上触发,所以你必须做这样的事情p.limbs.each {| l | p.limbs.destroy(1)}
为什么它不会被destroy_all触发?
因为这:
def destroy_all(conditions = nil) find(:all,:conditions => conditions).each { |object| object.destroy } end
它迭代关联的每个元素并对对象执行销毁操作而不是关联,这就是原因.
原文地址:https://www.jb51.cc/ruby/268725.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。