如何向Active Admin添加自定义过滤器?

时间:2011-11-02 16:15:40

标签: ruby-on-rails ruby ruby-on-rails-3 activeadmin

Active Admin允许我在索引页面上显示define filters,如下所示:

ActiveAdmin.register Promo do

  filter :name
  filter :address
  filter :city
  filter :state
  filter :zip

end

我想将上面的所有字段合并为一个,以便我可以搜索包含名称或完整地址中的搜索字符串的Promos。我的模型已经有一个我可以使用的命名范围:

class Promo < ActiveRecord::Base
  scope :by_name_or_full_address, lambda { |q| where('name LIKE :q OR address LIKE :q OR city LIKE :q OR state LIKE :q OR zip LIKE :q', :q => "%#{q}%") }
end

8 个答案:

答案 0 :(得分:28)

Active Admin使用meta_search gem作为其过滤器。 ORed条件语法允许在一个查询中组合多个字段,例如

Promo.metasearch(:name_or_address_contains => 'brooklyn')

在Active Admin DSL中,这转换为

ActiveAdmin.register Promo do

  filter :name_or_address, :as => :string

end

答案 1 :(得分:27)

Active admin使用元搜索。例如,您可以这样做:

filter :"subscription_billing_plan_name" , :as => :select, :collection => BillingPlan.all.map(&:name)

答案 2 :(得分:11)

要使用自定义过滤器,您可以创建范围函数并将其作为search_methods添加到模型中。

例如,在我的用户模型上:

search_methods :role_eq
scope :role_eq, -> (role) { where("? LIKE ANY(roles)", role) }

然后在users.rb中,我可以将我的范围用作自定义过滤器:

filter :role, label: "Roles", as: :select, collection: %w[ student teacher parent ]

答案 3 :(得分:6)

我找到了更好的方法。你只需要添加:

config.clear_sidebar_sections!

sidebar :filters do
  render partial: 'search'
end

然后使用构建器_searchActiveAdmin::FormBuilder部分内部创建表单,如下所示:

https://github.com/gregbell/active_admin/blob/master/lib/active_admin/filters/forms.rb

有关如何操作的更多信息,请查看以下要点:

https://gist.github.com/4240801

另一个想法是创建类:

module ActiveAdmin
  module Inputs
    class FilterCustomStringInput < FilterStringInput
      def input_name
        "#{super}"
      end
    end
  end
end

可以通过as: :custom_string调用,但我不喜欢这个主意,因为你很快就会发现,你需要创建custom_select等等......

答案 4 :(得分:4)

在活动管理员的较新版本中进行此类过滤的另一种方法:

# app/admin/my_model.rb
filter :my_custom_filter,
as: :numeric,
label: 'Custom Filter',
filters: [:eq]

然后在模型文件中添加以下2个功能

您的过滤逻辑:

def self.my_custom_filter_eq(value)
  where(column_1: value) # or probably a more complex query that uses the value inputted by the admin user
end

为Ransack注册新的过滤器

def self.ransackable_scopes(_auth_object = nil)
  %i(my_custom_filter_eq)
end

答案 5 :(得分:1)

我的模型 WithdrawalRequest 属于用户模型。

要按用户的电子邮件过滤提款请求,请写:

filter :user_id, :as => :select, :collection => User.all.map {|user| [user.email, user.id]}

答案 6 :(得分:1)

在2018年进行回答。ActiveAdmin使用Ransack。

在模型本身上,您需要添加Ransack格式化程序:

ransacker :my_custom_filter, formatter: -> (category_id) {
    ids = MyModel.where(category_id: category_id).pluck(:id) # return only id-s of returned items.
    ids.present? ? ids : nil # return ids OR nil!
} do |parent| # not sure why this is needed .. but it is :)
    parent.table[:id]
end 

在ActiveAdmin文件中,您需要指定规则:

filter :my_custom_filter_in, as: :select, collection: -> { Category.all } # sometimes my_custom_filter_eq - depending on what you want .. Specify different "as" when you need it. 

答案 7 :(得分:0)

这对我有用:

在我的模型中

  scope :active, -> { where(inactive_at: nil) }
  scope :inactive, -> { where.not(inactive_at: nil) }

  ...

  ransacker :listing_status, formatter: proc{ |status|
    ids = status == 'Active' ? active.ids : inactive.ids
    ids = ids.present? ? ids : nil
  }, splat_params: true do |parent|
    parent.table[:id]
  end

在我的管理文件中

filter :listing_status_in, as: :select, collection: %w(Active Inactive), label: 'Listing Status'