Rails 5 + Active Admin 2.0.0中after_destroy回调失效原因咨询
问题解决:Active Admin 2.0.0 中
after_destroy 回调不生效的处理方案 核心问题分析
你遇到的问题主要有两个可能原因:
- Active Admin 的控制器回调与模型回调触发逻辑不同,默认的
after_destroy回调在部分删除场景(比如批量删除)下不会触发; - 代码里存在拼写错误:
desable_something应为disable_something,这可能直接导致逻辑不执行。
具体解决方案
方案1:优先复用模型层回调(更可靠)
把回调放回模型文件,同时确保删除操作使用 destroy 而非 delete(delete 直接操作数据库,不会触发任何回调)。
模型文件代码示例:
class MyModel < ApplicationRecord after_destroy :trigger_account_disable private def trigger_account_disable Account.disable_something(account_id) if account_id.present? end end
检查项目中所有删除 MyModel 的代码:
- 替换
MyModel.delete(id)为MyModel.find(id).destroy - 替换
MyModel.delete_all(condition)为MyModel.where(condition).destroy_all
如果之前模型回调仅在部分环境生效,排查是否有以下情况:
- 生产/测试环境中使用了批量删除工具或跳过回调的代码(比如
skip_callback) - 删除操作被包裹在事务中,事务回滚导致回调逻辑未生效
方案2:在 Active Admin 中强制触发回调
如果必须在 Admin 层处理,需要覆盖单个删除动作,并自定义批量删除动作,确保所有删除场景都执行逻辑:
ActiveAdmin.register MyModel do # 覆盖单个删除的控制器动作 controller do def destroy # 先执行默认删除逻辑 super do |format| # 执行你的业务逻辑 Account.disable_something(resource.account_id) if resource.account_id.present? format.html { redirect_to collection_path, notice: '记录已删除' } end end end # 自定义批量删除动作,替代默认批量删除 batch_action :destroy, confirm: '确定要删除选中的记录吗?' do |ids| batch_action_collection.find(ids).each do |model| Account.disable_something(model.account_id) if model.account_id.present? model.destroy end redirect_to collection_path, notice: '批量删除完成' end end
关键注意点
- 务必修正拼写错误:
desable_something→disable_something,这是容易忽略的致命问题; - Active Admin 默认的批量删除会调用
destroy_all,不会触发控制器级别的after_destroy回调,必须自定义批量动作才能覆盖。
内容的提问来源于stack exchange,提问作者Anil Kohli
相关产品推荐
相关产品推荐

