可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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 #
回答1:
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.
回答2:
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.
回答3:
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)
回答4:
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.
回答5:
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