【问题标题】:How to trigger destroy child on change of the relationship to a different record in the child table?如何在更改与子表中不同记录的关系时触发销毁子项?
【发布时间】:2019-08-22 16:48:07
【问题描述】:

我们的父子关系是一对一的

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-rails ruby-on-rails-4


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 2016-10-01
      • 2019-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多