如何在ActiveAdmin中过滤IS NULL?

问题描述 投票:0回答:6

我有一个带有名为“map_id”的整数列的表,我想添加一个 activeadmin 过滤器来过滤此列是否为 NULL 或 IS NOT NULL。

如何实施?

我尝试了以下过滤器

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

但是,我收到以下错误消息:

# 的未定义方法“map_eq”

ruby-on-rails-3 activeadmin formtastic meta-search
6个回答
38
投票

如果有人在这个线程上发生了迟来的事情,现在有一种简单的方法可以在活动管理中过滤 null 或非 null :

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

不再需要向范围添加自定义方法来完成此操作。


15
投票

没有找到好的解决方案,但这里有一个方法。 Active_admin的过滤器是由meta_search完成的,您可以覆盖模型中meta_search自动生成的函数以获得您想要的行为,最好的方法是使用范围,因为您需要返回一个关系以便与其他查询链接/范围,如此处

所述

在您的模型中:

对于 :as=>:select 过滤器,acitve_admin 使用 _eq ,这里是 源代码

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.

希望这有帮助。


5
投票

似乎 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

您将看到这些范围的按钮出现(在顶部部分,在模型名称下,而不是在过滤器部分)


2
投票

新版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 条目。

这个帖子帮助了很多


0
投票

带有可搜查范围:

关于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

0
投票

在吐血试图找到一个可行的解决方案之后,以下是使它在 Rails 7.0 和 ransack 4.2.0 上对我有用的步骤:

  1. 在 active_admin 资源文件中定义自定义过滤器

    # app/admin/my_model.rb
    
    filter :by_map_id, label: 'Assigned', as: :select, collection: -> { [['none', 'none'], ['one', 1],['two', 2]] }
    
    
  2. 在相对 ActiveRecord 模型中定义一个新范围(或者类方法,如果您愿意):

    # app/models/my_model.rb
    
    ...
    
    scope :by_map_id, ->(id_value) { (map_id = id_value == 'none' ? nil : id_value; where(map_id: map_id)) if id_value }
    
    ...
    
    def self.ransackable_scopes(_auth_object = nil)
      %i(by_map_id)
    end
    
    
© www.soinside.com 2019 - 2024. All rights reserved.