On an ActiveAdmin page, filters can help make information more usable. But sometimes, we need to add filters that are more complex than normal, going beyond a simple 'where' clause applied to only one column of the table.
To achieve this, we'll start by defining the filter like this:
In the model, we'll then define a scope or class method that returns an Active Record Relation:
And finally, we'll need to specify that the scope is ransackable. This means we'll add the following to the model:
This example assumes we want to create a filter that receives a numeric value as a parameter, and for simplicity, we've limited the querying options to equality. But that's just one possibility – you can play around with other predicates and change param types to see what's most useful in your case.
It's important to mention that the filter has to match the scope or class method name and that it's not recommended to end it with any predicates used by ransack, like "eq", "contains", etc. This is because you could end up pointing the filter to a ransack generated scope.
As an example, let's add a filter that uses a date range for a custom column.
Suppose your model has a 'belongs to' relation with the user model, and the user has an activation date. Now, you want to filter the records belonging to a user that was activated between two dates.
Here's what goes in the admin model:
And in the model:
And that's it! We've only used a couple of examples here, but this code structure is the foundation for many other types of custom filters you may want to create, so you can tweak it to achieve a variety of goals.