Rails Admin is an excellent way of quickly creating a backend for your website. It’s simply perfect for that project that is focused on frontend but you still need a backend to do simple management tasks.
Although it’s very complete, sometimes you may want to customize a few things and for this you can create a custom action.
If you have, for example, a list of articles. It would be good if you could bulk publish them, instead of going and editing one by one. Fortunately this is possible and quite simple, although it’s not very clear in Rails Admin manual.
1. Create your custom action
Let’s create our custom action. Create file lib/rails_admin_publish.rb with the following content:
require 'rails_admin/config/actions' require 'rails_admin/config/actions/base' module RailsAdminPublish end module RailsAdmin module Config module Actions class Publish < RailsAdmin::Config::Actions::Base # There are several options that you can set here. # Check https://github.com/sferik/rails_admin/blob/master/lib/rails_admin/config/actions/base.rb for more info. register_instance_option :bulkable? do true end register_instance_option :controller do Proc.new do # Get all selected rows @objects = list_entries(@model_config, :destroy) # Update field published to true @objects.each do |object| object.update_attribute(:published, true) end flash[:success] = "#{@model_config.label} successfully published." redirect_to back_or_index end end end end end end
What exactly this does? Well, first it defines this action as bulkable. There are many other options that you can set here, check the comment next to that line for more information.
After that, we create a Proc with our action. In summary, it’s getting all entries and looping to update the attribute published. After that, it sets a flash message and redirect to index.
2. Let Rails Admin know that your custom action exists
Open config/initializers/rails_admin.rb and add the following code before RailsAdmin.config:
require Rails.root.join('lib', 'rails_admin_publish.rb')
Them add this inside RailsAdmin.config:
# Register the class in lib/rails_admin_publish.rb module RailsAdmin module Config module Actions class Publish < RailsAdmin::Config::Actions::Base RailsAdmin::Config::Actions.register(self) end end end end c.actions do # root actions dashboard # mandatory # collection actions index # mandatory new export history_index bulk_delete # member actions show edit delete history_show show_in_app # Set the custom action here publish do # Make it visible only for article model. You can remove this if you don't need. visible do bindings[:abstract_model].model.to_s == "Article" end end end
What it does is to first register the publish action and them tell Rails Admin where it should be visible. If you want to make it visible for all models, simply remove that visible part and it should work correctly.
That’s it, restart your server and test. The bulk action should be there.
In case you still have questions I’ve forked dummy_app, which is a sample app created to show Rails Admin, and used it to create a custom action. Check it out in Github https://github.com/fernandomm/dummy_app
Thanks, it is very clear 😉
Very clear, thank you very much !
Awesome post.
Don’t forget to add the en.yml file for custom bulk drop down names. Without it you’ll get an error in place of the drop down.
https://github.com/theodorton/rails_admin
how i can custom view?
Awesome post,
I would have paid you a beer if you had one of those plugins activated.
Thanks!
Many thanks!
You can write
“RailsAdmin::Config::Actions.register(self)”
at lib/rails_admin_publish.rb and so first “module” lines at “RailsAdmin.config” are not needed.
Hi, I’ll be surprised if you actually read this, but in lines 20 and 21 of the rails_admin_publish.rb file:
” # Get all selected rows
@objects = list_entries(@model_config, :destroy)”
I was wondering if it’s possible to change it so that instead of getting all the selected rows, it gets every row.
I’m not using Rails admin anymore so I can’t test it.
I guess you can do this by setting the pagination parameter of list_entries to false. Something like this:
@objects = list_entries(@model_config, :destroy, nil, false)
https://github.com/sferik/rails_admin/blob/219333b301e4cb845e947c4bb33892bf0a566129/app/controllers/rails_admin/main_controller.rb#L31