web-dev-qa-db-fra.com

Comment ajouter un filtre personnalisé à Active Admin?

Active Admin me permet de définir des filtres qui sont affichés sur la page d'index comme suit:

ActiveAdmin.register Promo do

  filter :name
  filter :address
  filter :city
  filter :state
  filter :Zip

end

Je souhaite combiner tous les champs ci-dessus afin que je puisse rechercher des promos contenant la chaîne de recherche sous forme de nom ou d'adresse complète. Mon modèle a déjà une portée nommée que je peux utiliser:

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
28
dkobozev

Active Admin utilise la gemme meta_search pour ses filtres. La syntaxe des conditions ORed permet de combiner plusieurs champs dans une requête, par exemple

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

Dans Active Admin DSL, cela se traduit par

ActiveAdmin.register Promo do

  filter :name_or_address, :as => :string

end
27
dkobozev

L'administrateur actif utilise la métarecherche. Par exemple, vous pouvez faire ceci:

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

Pour utiliser un filtre personnalisé, vous pouvez créer une fonction d'étendue et l'ajouter en tant que méthode_recherche dans le modèle. 

Par exemple, sur mon modèle utilisateur: 

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

Ensuite, dans users.rb, je peux utiliser ma portée en tant que filtre personnalisé:

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

J'ai trouvé un meilleur moyen de le faire. Vous avez juste besoin d'ajouter:

config.clear_sidebar_sections!

sidebar :filters do
  render partial: 'search'
end

Et ensuite, créez le formulaire à l'intérieur du _search partiel avec le générateur ActiveAdmin::FormBuilder comme il le faisait dans:

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

Pour plus d'informations sur la procédure à suivre, consultez le présent résumé:

https://Gist.github.com/4240801

Une autre idée est de créer une classe:

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

cela pourra invoquer as: :custom_string, mais je n'aime pas cette idée, car vous pourrez bientôt trouver qu'il vous faudra créer custom_select, etc.

6
Dmitry Polushkin

Réponse en 2018. ActiveAdmin utilise Ransack. 

Sur le modèle même, vous devez ajouter le formateur 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 

Dans le fichier ActiveAdmin, vous devez spécifier la règle:

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
knagode

J'ai model WithdrawalRequest qui appartient à User model.

Pour filtrer les demandes de retrait par courrier électronique, vous devez écrire:

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