Как добавить пользовательский фильтр в Active Admin? - PullRequest
29 голосов
/ 02 ноября 2011

Active Admin позволяет мне определять фильтры , которые отображаются на странице индекса следующим образом:

ActiveAdmin.register Promo do

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

end

Я хотел бы объединить все поля выше в одно, так что яможете искать промо, которые содержат строку поиска в имени или полном адресе.У моей модели уже есть именованная область, которую я могу использовать:

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

Ответы [ 7 ]

28 голосов
/ 28 ноября 2011

Active Admin использует гем meta_search для своих фильтров.Синтаксис условий ORed позволяет объединять несколько полей в одном запросе, например

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

В Active Admin DSL это переводится как

ActiveAdmin.register Promo do

  filter :name_or_address, :as => :string

end
28 голосов
/ 24 ноября 2011

Активный админ использует метапоиск.Например, вы можете сделать это:

filter :"subscription_billing_plan_name" , :as => :select, :collection => BillingPlan.all.map(&:name)
11 голосов
/ 30 июля 2014

Чтобы использовать пользовательский фильтр, вы можете создать функцию области и добавить ее в качестве search_methods в модель.

Например, на моей модели User:

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 ]
6 голосов
/ 08 декабря 2012

Я нашел лучший способ сделать это. Вам просто нужно добавить:

config.clear_sidebar_sections!

sidebar :filters do
  render partial: 'search'
end

И затем создайте форму внутри _search частичного с помощью построителя ActiveAdmin::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 и так далее ...

1 голос
/ 16 ноября 2018

Ответ в 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. 
1 голос
/ 16 сентября 2017

У меня есть модель WithdrawalRequest , которая принадлежит Модель пользователя .

Для фильтрации запросов на вывод средств по электронной почте пользователя необходимо написать:

filter :user_id, :as => :select, :collection => User.all.map {|user| [user.email, user.id]}
0 голосов
/ 24 апреля 2019

Это сработало для меня:

В моей модели

  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'

...