如何在 Rails 管理员中创建自定义批量操作?

How do I create a custom bulk action in Rails Admin?

"how to create a custom bulk action in Rails Admin"的基础问题在项目中被问过多次,甚至提到这里被问过,但从来没有在这里做过:

在寻找这个问题的答案的过程中,我最终自己回答了。在我关于如何创建自定义更新操作的回答中,包括了一个基本示例。

假设/用例:

您有一个具有 has_one 类别关系的用户模型。

期望的结果:

en.yml

en:
  admin:
    actions:
      bulk_update_category:
        title: Bulk update category
        breadcrumb: Bulk Update
        menu: Bulk update category
        bulk_link: Update category for selected %{model_label_plural}

config/initializers/rails_admin.rb

module RailsAdmin
  module Config
    module Actions
      class BulkUpdateCategory < RailsAdmin::Config::Actions::Base
        RailsAdmin::Config::Actions.register(self)

        register_instance_option :collection do
          true
        end

        register_instance_option :http_methods do
          [:post]
        end

        register_instance_option :controller do
          proc do
            @users = list_entries(@model_config)
            if request.params['bulk_step'].blank? # Selecting a category
              if @users.blank?
                flash[:error] = 'No users selected to update'
                redirect_to index_path
              else
                render @action.template_name
              end
            elsif request.params['new_category_id'].present?
              @new_category = Category.find(request.params['new_category_id'])
              @users.update_all(category_id: @new_category.id)
              redirect_to index_path, flash: {info: "Category updated to #{@new_category.name} for #{@users.count} users"}
            else
                flash[:error] = 'No category selected'
                render @action.template_name
            end
          end
        end

        register_instance_option :bulkable? do
          true
        end
      end
    end
  end
end

RailsAdmin.config do |config|
  config.actions do
    dashboard                     # mandatory
    index                         # mandatory
    new
    export
    bulk_delete
    show
    edit
    delete
    show_in_app

    bulk_update_category do
      only ['User']
    end
  end

  config.included_models = ['User']
end

app/views/rails_admin/main/bulk_update_category.html.erb

    <style type="text/css">
      th, td{
        padding: 5px;
      }
    </style>

    <form action="" method="POST">
      <input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" />
      <input type="hidden" name="bulk_action" value="<%= request.params['bulk_action'] %>" />
      <input type="hidden" name="bulk_step" value="update" />
      <% request.params['bulk_ids'].each do |bulk_id| %>
        <input type="hidden" name="bulk_ids[]" value="<%= bulk_id %>" />
      <% end %>

      <label for="new_category_id">Please choose the category where you would like to move these users:</label><br />
      <select name="new_category_id" id="new_category_id">
        <% Category.all.order(:name).each do |category| %>
          <option value="<%= category.id %>">
            <%= category.name %>
          </option>
        <% end %>
      </select>
      <br /><br />
      <input type="submit" value="Update category" />

      <h3>Users to be updated:</h3>
      <table>
        <tr>
          <th align="center">User</th>
          <th align="center">Current Category</th>
          <th align="center">Date</th>
        </tr>
        <% @users.each do |user| %>
          <tr>
              <td><%= user.name %></td>
              <td><%= user.category.name %></td>
              <td><%= user.created_at.to_s %></td>
          </tr>
        <% end %>
      </table>
      <br /><br />
      <% if @users.count >= 10 %>
        <input type="submit" value="Update category" />
      <% end %>
    </form>