如何重写ActiveAdmin的batch_action并传递对象实现动态确认提示
解决方案
实现原理
ActiveAdmin 默认batch_action的confirm参数是服务端渲染页面时就生成的静态值,无法动态读取用户选中条目的关联数据,因此需要通过自定义复选框属性+监听批量操作事件的方式实现动态确认提示。
步骤1:改造可选择列,存储单作者书籍数
替换默认的selectable_column,给每个复选框新增自定义data属性存储当前作者的书籍数量:
# 你的ActiveAdmin Authors配置文件中index代码块 index do # 替换原有默认的selectable_column selectable_column do |author| check_box_tag "batch_action_item_ids[]", author.id, false, class: "batch_action_item", data: { book_count: author.books.count } end # 你原有其他列逻辑保持不变,比如删除列: column I18n.t('active_admin.delete') do |author| link_to I18n.t('active_admin.delete'), admin_author_path(author), method: :delete, data: { confirm: t('admin.authors.confirmations', quantity: author.books.count) } end # 调整batch_action定义,移除静态confirm参数 batch_action :destroy do |ids| # 批量删除逻辑可按需补充,比如加操作提示 Author.destroy(ids) redirect_to collection_path, notice: "已删除选中的#{ids.size}位作者" end # 其他原有列逻辑... end
步骤2:添加前端监听逻辑,动态生成确认提示
在ActiveAdmin自定义JS文件(通常为app/assets/javascripts/active_admin_custom.js)中添加批量操作事件监听:
// 监听ActiveAdmin批量操作触发前的钩子事件 $(document).on('batch_action:before', function(e, action) { // 仅拦截批量删除操作 if (action !== 'destroy') return true; // 累加所有选中作者的总书籍数 let totalBooks = 0; $('input.batch_action_item:checked').each(function() { totalBooks += parseInt($(this).data('book-count')) || 0; }); // 生成确认文案,可直接复用你的翻译模板 // 如果已配置i18n-js可直接调用:const confirmMsg = I18n.t('admin.authors.confirmations', {quantity: totalBooks}) // 未配置i18n-js可以直接替换为你的文案模板 const confirmMsg = `确认删除选中作者?该操作将同步删除${totalBooks}本关联书籍`; // 用户取消则终止批量操作 if (!confirm(confirmMsg)) { e.preventDefault(); return false; } });
可选优化
给Author模型添加books_count计数器缓存,避免每次渲染页面都关联查询书籍数量,提升页面加载性能。
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

