Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

The base question of "how to create a custom bulk action in Rails Admin" has been asked multiple times in the project, and even referred here to be asked, but has never been done here:

  • "Looking for sample of custom bulk action" https://github.com/sferik/rails_admin/issues/2647

  • "How do I do custom bulk action?" https://github.com/sferik/rails_admin/issues/2493

  • "How to create a bulk edit form for rails_admin ?" https://github.com/sferik/rails_admin/issues/2138

In the process of looking for the answer to this question, I ended up answering it myself. Included is a basic example in my answer of how to create a custom update action.

Assumptions / use case:

You have a User model with a has_one Category relationship.

Desired outcome:

  • Add a way to select multiple Users and click an "update category for selected" option in the bulk actions dropdown
  • On the following page, similar to the bulk_delete action, confirm the category you want to update it to
  • Update category on users after submitting confirmation form
like image 711
streetlogics Avatar asked Jan 26 '23 20:01

streetlogics


1 Answers

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

Preview dropdown

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

enter image description here

    <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>

enter image description here

like image 184
streetlogics Avatar answered Jan 29 '23 21:01

streetlogics