我有一个名为“map_id”的整数列的表,我想添加一个 activeadmin 过滤器来过滤该列是否为空或不为空。
这怎么可能实现?
我尝试了以下过滤器
filter :map_id, :label => 'Assigned', :as => :select, :collection => {:true => nil, :false => ''}
但是,我收到以下错误消息:
未定义的方法 `map_eq' 用于#
我有一个名为“map_id”的整数列的表,我想添加一个 activeadmin 过滤器来过滤该列是否为空或不为空。
这怎么可能实现?
我尝试了以下过滤器
filter :map_id, :label => 'Assigned', :as => :select, :collection => {:true => nil, :false => ''}
但是,我收到以下错误消息:
未定义的方法 `map_eq' 用于#
如果有人迟到了这个线程,现在有一种简单的方法可以在活动管理员中过滤 null 或非 null :
filter :attribute_present, :as => :boolean
filter :attribute_blank, :as => :boolean
不再需要向作用域添加自定义方法来完成此操作。
没有找到一个好的解决方案,但这里有一个方法。Active_admin 的过滤器由 meta_search 完成,您可以在模型中覆盖 meta_search 自动生成的函数以获得您想要的行为,最好的方法是使用范围,因为您需要返回一个关系才能与其他查询链接/scopes,如此处所述
在您的模型中:
对于 :as=>:select 过滤器,acitve_admin 使用 _eq wheres,这里是源代码
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
在您的 ative_admin 注册块中:
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.
希望这有帮助。
似乎 search_method 在最近的 Rails 版本中不起作用,这是另一个解决方案:
为您的模型添加范围:
scope :field_blank, -> { where "field is null" }
scope :field_not_blank, -> { where "field is not null" }
添加到 /app/admin/[你的模型]
scope :field_blank
scope :field_not_blank
您将看到这些范围的按钮出现(在顶部,在模型名称下,而不是在过滤器部分)
新版 ActiveAdmin 使用 Ransacker。我设法让它以这种方式工作:
filter :non_nil_map_id, :label => 'Assigned', :as => :select, :collection => [['none', 'none'], ['one', 1],['tow', 2]]
为了保持一致性,我从@Gret 答案中获取了相同的代码,只是更改了过滤器名称
ransacker :not_nil_map_id, :formatter => proc {|id| map_id != 'none' ? id : 'none' } do |parent|
parent.table[:id]
end
如果 id 为“none”,这将触发对nil的搜索,并且活动记录将返回所有nil id条目。
这个线程帮助很大。
使用可洗劫范围:
在 ActiveAdmin 资源定义上:
filter :map_id, :label => 'Assigned', as: :select, :collection => [['Is Null', 'none'], ['Not null', 'present']]
在您的模型上:
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