Rails-检查父对象是否被销毁并在依赖项上调用destroy

时间:2019-03-27 04:22:37

标签: ruby-on-rails activemodel

我有以下内容:

class ModelA < ApplicationRecord
  has_many :model_bs, dependent: :destroy
end

class ModelB < ApplicationRecord
  belongs_to :model_a
  after_destroy :action_only_if_model_a_exists

  private

  def action_only_if_model_a_exists
    # Do things
  end
end

当我调用model_a.destroy时,我需要能够在ModelB的action_only_if_model_a_exists回调中确定相关的ModelA是否仍然存在或是否也将要销毁。

是否存在一种不错的内置Rails方式?还是我需要沿着在较早的回调(例如before_destroy)中在ModelA中设置标志的路径走下去,然后可以在ModelB的回调中进行检查? / p>

修改

我已经进行了多次测试,并确认在action_only_if_model_a_exists回调中,执行以下操作无济于事:

> model_a.persisted?
true

> model_a.destroyed?
false

> model_a.frozen?
false

3 个答案:

答案 0 :(得分:2)

您可以在子对象中使用 destroyed_by_association 属性来查看对象是否作为其父对象的 dependent: :destroy 的一部分被销毁。

答案 1 :(得分:1)

我找不到执行此操作的好方法,因此我决定执行以下操作:

class ModelA < ApplicationRecord
  attr_accessor :destroying?
  has_many :model_bs, dependent: :destroy

  def destroy
    self.destroying? = true
    super
  end
end

class ModelB < ApplicationRecord
  belongs_to :model_a
  after_destroy :action_only_if_model_a_exists

  private

  def action_only_if_model_a_exists
    if !model_a.destroying?
      # Do things
    end
  end
end

答案 2 :(得分:0)

可能最干净的方法是在before_destroy中使用ModelA回调在所有关联的ModelB上调用所需的函数

class ModelA < ApplicationRecord
  has_many :model_bs, dependent: :destroy

  before_destroy { |model_a| model_a.model_bs.each { |model_b| model_b. action_only_if_model_a_exists } }
end

当然,action_only_if_model_a_exists不必是私有的。

此外,您将要考虑给定的model_bs可能有多少model_a,并在必要时考虑使用in_batches而不是each

更新

好的,根据您最新的解释,现在我的理解与以前相反,接下来该怎么办?

class ModelB < ApplicationRecord
  belongs_to :model_a
  after_destroy :action_if_not_called_from_model_a

  private

  def action_if_not_called_from_model_a
    if !caller.join.match(/model_a/)
      # Do things
    end
  end
end