Heading image for post: Customize ActiveAdmin Index Filters

Ruby

Customize ActiveAdmin Index Filters

Profile picture of Josh Branchaud

ActiveAdmin allows us to quickly bootstrap an admin interface to our application. One of the features we get out of the box is a robust, comprehensive filtering sidebar. When viewing a resource's index page with hundreds of records, filtering allows us to narrow down to a digestible subset.

Unfortunately, the set of filters generated by ActiveAdmin for a particular model can sometimes be a bit hairy. If there are lots of fields and associations, you can end up with way more filters than you need, detracting from the user experience.

One solution is to remove the filters altogether.

ActiveAdmin.register Post do
  config.filters = false
end

This is a bit drastic though. Perhaps we can find some middle ground by customizing the filters a bit. In the rest of this post, I'll layout some approaches we can take to make our filters cleaner and more directed.

Table of Contents


Remove Specific Filters

Often times the majority of the filters ActiveAdmin produces are fine. There are only one or two that need to be removed. You can provide one or more attributes or associations to be excluded from the set of filters with the remove_filter directive.

ActiveAdmin.register Post do
  remove_filter :developer, :max_likes
end

Declare Specific Filters

Perhaps there are only a couple filters you'd like to include. The rest of them ought to be excluded. Instead of declaring a large list of filters to remove -- a list which may need to be updated as the model changes -- you can explicitly declare the filters you'd like. This works because, when adding a filter, all the default filters are removed.

ActiveAdmin.register Post do
  filter :developer # association from `belongs_to`
end

If you aren't wanting to remove all the default filters when modifying a filter as we did in the above example, include the preserve_default_filters! directive before your filter changes.

ActiveAdmin.register Post do
  preserve_default_filters!
  filter :developer
  filter :max_likes, label: "Maximum Likes"
end

Change A Filter's Label

You can customize the label used by a particular filter -- just include the label option with the preferred text.

ActiveAdmin.register Post do
  filter :max_likes, label: "Maximum Likes"
end

If you are using i18n for your model's name elsewhere, you'll need to be mindful of that here as well.

Scope A Filter's Collection

The collection of things that are included in a drop down filter defaults to all of those things. For example, if we were to fully spell out the filter's default collection for our developer association, it would look something like this.

ActiveAdmin.register Post do
  preserve_default_filters!
  filter :developer, collection: -> { Developer.all }
end

We can take advantage of that syntax to scope the collection in whatever way we would like. For example, to only include developers with at least one post, we can scope our developer collection like so.

ActiveAdmin.register Post do
  filter :developer, collection: -> {
    Developer.preload(:posts).select { |dev| dev.posts.present? }
  }
end

Change The String Representation

There are two scenarios in which you'll want to adjust the string representation of items in a drop down. The more common is when ActiveAdmin doesn't know how to represent an object, so it uses the fallback object representation (e.g. #<Klass:0x401b3998 ...>). The other is when the existing string representation just isn't what you want. In either case, the simplest solution is to add or modify to_s for the particular model. If we want to restrict our changes to the app/admin directory, we can again adjust the collection.

ActiveAdmin.register Post do
  filter :developer, collection: -> {
    Developer.all.map { |dev| [dev.email, dev.id] }
  }
end

In this case, I chose to display a developer's email instead of the default of their username. We have to provide a tuple with the string representation and the id. We have to provide the id for ActiveAdmin to be able to look up and filter by a particular developer.

Coerce The Input Type

ActiveAdmin does its best to infer the type of input that should be used for a particular attribute, but it doesn't always nail it on the head. We can use the :as option to coerce the input type to something else that makes more sense. For example, a drop down with yes and no options would be better off as a couple check boxes. A field that is an integer would be easy to interact with using a number input.

ActiveAdmin.register Post do
  filter :tweeted, as: :check_boxes
  filter :max_likes, as: :number
end

Specify HTML Attributes

We can even go a step further by specifying some attributes of an input field using the input_html option. For example, we can set the step, min, and max of our number input like so.

ActiveAdmin.register Post do
  filter :max_likes,
    as: :number,
    input_html: { step: 10, min: 0, max: 100 }
end

Go Beyond

All of the examples I have laid out in this post can, generally speaking, be mixed and matched. If you want to do something that I haven't explicitely laid out, just give it a try. The syntax for filters is pretty flexible, so try bending it in various ways to meet your needs.

The filter sidebar is powered by Ransack and Formtastic. Feel free to dig into those repositories for even more insight. To create filters that use completely custom search/filtering, I recommend reading about Using Ransackers and checking out this blog post.

Have fun and build the filters of your dreams!


Cover image by Guillaume Lebelt on Unsplash.com

More posts about rails activeadmin Ruby