我遇到了这样的情况:
class Shop < ActiveRecord::Base
has_many :services, dependent: :destroy
end
class Service < ActiveRecord::Base
has_many :model_weeks, dependent: :destroy
end
class ModelWeek < ActiveRecord::Base
before_destroy :prevent_destroy, if: :default?
private
def prevent_destroy
false
end
end当我试图摧毁一家商店时,我得到了ActiveRecord::RecordNotDestroyed: Failed to destroy the record,因为它首先开始销毁相关的记录,并且通过ModelWeek中的回调来阻止它。
我可以很容易地取消默认的ModelWeek时,摧毁一个商店,只有当我可以抓住它。在引发上述异常之前,不会触发before_destroy模型中的Shop。
那么,是否有办法在商店模型中捕捉到这一点,或者如果没有,是否有可能在ModelWeek中“知道”销毁是由父方触发的?我研究了解析调用者,但它没有提供任何有用的东西,而且无论如何都会很混乱.
发布于 2015-11-20 10:18:19
经过一些研究和测试,这是我想出的:
这是调用方法的顺序(do_before_destroy是在before_destroy回调中指定的任何方法):
因此,在父母(商店)的销毁方法中,我可以处理任何防止孩子被破坏(ModelWeek)的事情:
# Shop
def destroy
# default is a scope
ModelWeek.default.where(service_id: self.services.pluck(:id)).each do |m|
m.unset_default
end
super
end在此之后,没有任何东西能阻止对儿童的破坏,而且链条仍未被阻止。
更新
还有更好、更干净的解决方案,无需覆盖父级的destroy并执行任何查询:
class Shop < ActiveRecord::Base
has_many :services, dependent: :destroy, before_remove: :unset_default_week
private
def unset_default_week(service)
service.model_weeks.default.unset_default
end
end发布于 2017-08-06 18:46:31
我用一个有趣的方法解决了这个问题,您只需要将before_destroy行放在关联线之前,它就会在删除关联之前运行before_destroy。
发布于 2015-11-19 18:15:01
因为rails有从相关的孩子到父母的破坏链,这真的是有意义的,对吗?为了简单起见,我们可以像这样在ModelWeek中覆盖破坏方法:
class ModelWeek < ActiveRecord::Base
# before_destroy :prevent_destroy, if: :default?
def destroy
unless default?
super
end
end
endhttps://stackoverflow.com/questions/33809336
复制相似问题