我有以下内容:
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
答案 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