首页 > 解决方案 > 如何在更改与子表中不同记录的关系时触发销毁子项?

问题描述

我们的父子关系是一对一的,其中

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 发生变化,我们想要触发删除/销毁子级。

标签: ruby-on-railsruby-on-rails-4

解决方案


我认为您可以利用 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

推荐阅读