Question

I've a table with an integer column called "map_id", I want to add an activeadmin filter to filter if this column IS NULL or IS NOT NULL.

How could this be implemented ?

I tried the following filter

filter :map_id, :label => 'Assigned', :as => :select, :collection => {:true => nil, :false => ''}

But, I get the following error message :

undefined method `map_eq' for #

Was it helpful?

Solution

Not found a good solution but here is a how. filters of Active_admin are accomplished by meta_search, you can override the functions automatically generated by meta_search in your model to get the behavior that you want, the best way is to use the scope since you need to return a relation in order to chain with other query/scopes, as stated here

in your model:

for :as=>:select filters, acitve_admin use the _eq wheres, here is the source code

scope :map_eq, 
        lambda{ |id|
        if(id !='none')
            where( :map_id=> id)
        else
            where( :map_id=> nil)
        end
        }

#re-define the search method:
search_method :map_eq, :type => :integer

in your ative_admin register block:

filter :map_id, :label => 'Assigned', :as => :select, :collection => [['none', 'none'], ['one', 1],['tow', 2]]

# not using :none=>nil because active_admin will igore your nil value so your self-defined scope will never get chained.

Hope this help.

OTHER TIPS

If anyone is happening on this thread belatedly, there is now an easy way to filter for null or non null in active admin :

filter :attribute_present, :as => :boolean 
filter :attribute_blank,   :as => :boolean  

It is no longer necessary to add a custom method to the scope to accomplish this.

seems search_method doesn't work in recent rails version, here is another solution:

add scope to your model:

  scope :field_blank, -> { where "field is null" }
  scope :field_not_blank, -> { where "field is not null" } 

add to /app/admin/[YOUR MODEL]

   scope :field_blank
   scope :field_not_blank

you will see buttons for these scopes appear (in top section, under model name, not in filter section)

The new version of ActiveAdmin uses Ransacker. I manage to got it working this way:

On the admin

filter :non_nil_map_id, :label => 'Assigned', :as => :select, :collection => [['none', 'none'], ['one', 1],['tow', 2]]

For consistency, I took the same code from @Gret answer just changing the filter name

On your model

ransacker :not_nil_map_id, :formatter => proc {|id|  map_id != 'none' ? id : 'none' } do |parent|
    parent.table[:id]
end

This should trigger a search against nil in case the id is 'none', and active record will return all the nil id entries.

This thread helped a lot.

With ransackable scopes:

On the ActiveAdmin resource definition:

filter :map_id, :label => 'Assigned', as: :select, :collection => [['Is Null', 'none'], ['Not null', 'present']]

On your model:

scope :by_map_id, ->(id) { (id == 'none' ? where(map_id: nil) : where('map_id IS NOT NULL')) }

def self.ransackable_scopes(_auth_object = nil)
  %i[by_map_id]
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top