ruby-on-rails - 如何在更改与子表中不同记录的关系时触发销毁子项?
问题描述
我们的父子关系是一对一的,其中
parent.child_id = child.id
parent.child_id 很可能也有可能更改为不同的 child_id。不删除父级。我们如何自动销毁/删除已被此操作孤立的子记录?
我们的模型看起来像这样:父
class parent < ActiveRecord::Base
belongs_to :child, dependent: :destroy
after_commit :destroy_orphans, on: [:create, :update]
def destroy_orphans
Child.where.not(id: Parent.all.pluck(:child_id)).destroy_all
end
end
我们已经添加了 destroy_orphans 方法来完成此操作,但它增加了可能不需要存在的查询开销。
孩子
class child < ActiveRecord::Base
has_one :parent, inverse_of: :child, dependent: :nullify
before_save { build_parent unless parent && !parent&.child_id.nil? }
end
如果父级的 child_id 发生变化,我们想要触发删除/销毁子级。
解决方案
我认为您可以利用 Rails 活动记录中提供的 previous_changes 选项(https://apidock.com/rails/ActiveModel/Dirty/previous_changes)来实现此目的。我们可以获取父级的前一个子级并删除该子级。试试下面,
class parent < ActiveRecord::Base
belongs_to :child, dependent: :destroy
after_commit :destroy_orphans, on: [:create, :update], if: -> { previous_changes['child_id'].present? }
def destroy_orphans
previous_child = Child.find_by(id: previous_changes['child_id'].first)
previous_child.destroy unless previous_child.parent.present?
end
end
推荐阅读
- python - 如何标记一个函数不是 pytest 的测试?
- python - Python“监狱”在xinetd上没有输出
- angular-dart - AngularDart 移动网络应用
- azure - 函数V2:Nuget包DocumentFormat.OpenXml 2.8.1遇到异常
- ruby-on-rails - Ruby: Disable to use link massively
- android - 开放测试期结束后,抢先体验应用会自动卸载吗?
- python - matplotlib 不使用动画功能
- openthread - 在 Simplelink cc2640r2f (Launchxl-CC2640R2) 上构建和刷新 openthread
- excel - EXCEL:A列输入到B列输出
- c# - .Net / C# 解释