微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ruby-on-rails – after_destroy子回调可以保存父项的依赖关系,在父项被销毁时会导致问题

我有一种情况,我希望在另一个对象被销毁后更新父对象的依赖项.以下是类层次结构的示例:

class Parent < ActiveRecord::Base
  has_one  :info,:dependent => :destroy
  has_many :conditions,:dependent => :destroy
  ....
end

class Info < ActiveRecord::Base
  belongs_to :parent

  def recalculate
    # Do stuff
  end
  ....
end

class Condition < ActiveRecord::Base
  belongs_to :parent
  has_one :condition_detail

  after_destroy :update_info

  def update_info
    parent.info.recalculate
    parent.info.save(:validate => false)
  end
  ....
end

问题是当父节点被销毁时,它会销毁这个条件,然后它会引发after_destroy回调并在信息对象被销毁后保存它.所以在父母被破坏后,信息仍然存在.如果我没有绕过验证,保存将无声地失败,这是我不想要的.并使用保存!提出异常.

Condition上的回调必须是after_destroy,否则Info上的重新计算方法将无法正确表示关系状态以计算它需要的内容.

我觉得当父母被摧毁时我需要一种绕过回调的方法,但我不认为这是可能的.我不能使用dependent => delete_all因为它不会破坏Condition的子节点.我试过看看是否有一种方法可以判断父母是否已经对其进行了销毁并使用该信息来绕过after_destroy中的保存,但这似乎也没有用.

任何帮助将不胜感激,谢谢!

解决方法

我看到有两种选择:

>不要在Condition上使用after_destroy回调,而是期望任何正在销毁Condition的人重新计算信息.这是最干净的,因为你将两个独立的意图分离:对象破坏和计算.如果有一天你想要一次破坏2个条件并且只有在两个条件被销毁之后才重新计算,你可以看到这会更有用.你不能通过回调来做到这一点.它还与Law of Demeter更紧密地对齐 – Condition.destroy的调用调用info.recalculate比调用parent.info.recalculate的Condition更好.

如果您真的想要在Condition中打包此行为,请创建一个调用的#destroy_and_recalculate函数,而不仅仅是带有隐藏式回调的#destroy.对于呼叫者来说,您将开始重新计算更为明显.
>删除:dependent =>销毁父级的:条件关联,并将其替换为您自己的Parent上的before_destroy回调,这将导致条件在没有回调的情况下被销毁.

在Condition中,我会创建这个方法,例如#destroy_without_callbacks,并在其中销毁Condition的子节点,然后导致条件删除自身.

功能:dependent => destroy很棒,但是对于像这样的循环,我认为迄今为止最清晰的方法是通过消除一些魔法并管理对象和进程生命周期来使其非常清晰.更明确地说.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐