2015-10-23 7 views
5

Sagen wir, ich User-Klasse mit einem haben: E-Mail-Feld. Angenommen, ich verwende activeadmin, um Benutzer zu verwalten.Activeadmin: wie für Zeichenketten filtern, die zwei oder mehr Suchbegriffen entsprechen

Einen Filter, der E-Mails zurückgibt, die eine Zeichenfolge übereinstimmen, z.B. "Smith", ist sehr einfach. In admin/user.rb, schließe ich gerade die Linie

filter :email 

Das gibt mir einen Filter-Widget, das die Arbeit erledigt.

Allerdings ist dieser Filter nicht mich für die Kreuzung von mehreren Begriffen suchen lassen. Ich kann nach E-Mails suchen, die "smith" enthalten, aber nicht nach E-Mails, die sowohl "smith" als auch ".edu" enthalten.

Google sagt mir, dass activerecord Ransack unter der Haube verwendet, und Ransack demo hat einen "fortgeschrittenen" Modus, der mehrere Begriffssuchen erlaubt.

Was ist der einfachste Weg, um einen mehr Begriff Such-Widget in activeadmin zu bekommen?

Idealerweise hätte ich gerne ein Widget, mit dem ich smith .edu oder smith AND .edu eingeben kann, um nach E-Mails zu filtern, die beide Begriffe enthalten.

+1

arbeiten Das sieht ähnlich aus: http://www.scriptscoop.net/t/2e4ac6d6ff33/rails-active-admin-filter-for-multiple-words-search.html – TinMonkey

+0

zu Verwenden Sie die MLtiple-Feldsuche, die Sie verwenden würden: filter: email_or_first_name_cont. Ich denke (habe es noch nie probiert, also bin ich mir nicht einmal sicher, ob es logisch ist anzunehmen, dass es funktioniert). Du könntest versuchen, filter: email_or_email_cont' :) –

+0

Ich war damit zwar einfach, aber 'filter: email_or_email_cont' scheint nicht den Job erledigen. :(Danke trotzdem! –

Antwort

4

gibt es einfache Lösung ranasckable Bereiche

So etwas wie dies in Ihrem Modell setzen mit

class User < ActiveRecord::Base 
    .... 
    scope :email_includes, ->(search) { 
     current_scope = self 
     search.split.uniq.each do |word| 
     current_scope = current_scope.where('user.email ILIKE ?', "%#{word}%") 
     end 
     current_scope 
    } 

    def self.ransackable_scopes(auth_object = nil) 
     [ :email_includes] 
    end 
end 

Danach können Sie Filter mit AA DSL

Wie

filter :email_includes, as: :string, label: "Email" 
hinzufügen

UPD

sollte, wenn Änderung email_contains_any zu email_includes

+0

Diese Suchvorgänge funktionieren, wenn ich sie in der Konsole ausführen, aber ich kann sie nicht von activeadmin arbeiten. AA wird den Suchstring nicht in ein Array von Begriffen aufteilen. Ich muss noch benutze meine eigene AA-Gabel. Mache ich etwas falsch? –

+0

@dB ', aus Gründen, warum wir '' '_any''' nicht verwenden können, ändern' '' email_contains_any''' zu '' email_includes''' – Fivell

+0

Ah, danke, das funktioniert, und es ist eine viel bessere Lösung als meine selbst. Ist das irgendwo dokumentiert?Erläutern die ActiveRecord-Dokumente, wie diese mehrzeiligen Suchen durchgeführt werden? –

3

Fügen Sie einfach drei Filter zu Ihrem Modell:

filter :email_cont 
filter :email_start 
filter :email_end 

Es Ihnen eine flexible Möglichkeit gibt Ihre Suche zu verwalten.

enter image description here

Dieser Filter führt nächste SQL-Code:

SELECT "admin_users".* FROM "admin_users" 
WHERE ("admin_users"."email" ILIKE '%smith%' AND 
     "admin_users"."email" ILIKE '%\.edu') 
ORDER BY "admin_users"."id" desc LIMIT 30 OFFSET 0 

Ich gehe davon aus, dass genau das, was Sie suchen.

+0

Das ist in der Nähe, aber ich brauche tatsächlich etwas, das mehrere Abfragen in der E-Mail entspricht. Suche am Anfang, Mitte und Ende schneidet es nicht ganz für mich. :(Danke, tho. –

+0

Sorry dass sollte lesen "überall in der E-Mail". –

6

Ich habe eine Lösung gefunden, aber es ist nicht schön.

Die gute Nachricht ist, dass Ransack keine Probleme mit mehreren Begriffen sucht hat. Diese Suchen verwenden das "Prädikat" cont_all. Die folgende Zeile funktioniert, um E-Mails mit 'smith' und '.edu' zu finden.

Da diese Suchen in Ransack einfach sind, sind sie wahrscheinlich in ActiveAdmin einfach, nicht wahr? Falsch! Um sie zum Arbeiten zu bringen, musste ich drei Dinge tun.

  1. Ich habe eine benutzerdefinierte Ransack Methode (auch bekannt als ransacker) in User.rb. Ich nannte den Ransacker email_multiple_terms.

    class User < ActiveRecord::Base 
    
    # ... 
    
    ransacker :email_multiple_terms do |parent| 
        parent.table[:path] 
    end 
    
  2. erklärte ich einen Filter in meinem activeadmin Armaturenbrett, und es mit dem Ransacker verbunden. Beachten Sie, dass das Suchprädikat cont_all an den Ransacker-Namen angehängt wird.

admin/User.rb:

ActiveAdmin.register User do 

# ... 

filter :email_multiple_terms_cont_all, label: "Email", as: :string 

Diese Zeile erzeugt das Filter-Widget in Activeadmin. Wir sind fast da. Noch ein Problem: Activeadmin sendet Suchanfragen als eine einzige Zeichenfolge an Ransack (z. B. "smith .edu"), während unser Ransacker die Suchbegriffe als ein Array will. Irgendwo müssen wir die einzelne Zeichenfolge in ein Array von Suchbegriffen umwandeln.

  1. Ich modifizierte activeadmin, um den Suchstring unter bestimmten Bedingungen zu teilen. Die Logik befindet sich in einer Methode, die ich zu lib/active_admin/resource_controller/data_access.rb hinzugefügt habe.

    def split_search_params(params) 
        params.keys.each do |key| 
        if key.ends_with? "_any" or key.ends_with? "_all" 
         params[key] = params[key].split # turn into array 
        end 
        end 
        params 
    end 
    

Ich rief dann diese Methode innerhalb apply_filtering.

def apply_filtering(chain) 
     @search = chain.ransack split_search_params clean_search_params params[:q] 
     @search.result 
    end 

Dieser Code ist in meiner eigenen Gabel von activeadmin lebt, hier: https://github.com/d-H-/activeadmin

also mehrere Begriff Suche zum Laufen zu bringen, die Schritte 1 und 2 oben, und meine Gabel von A.A. umfasst in Ihrem Gemfile:

gem 'activeadmin', :git => 'git://github.com/d-H-/activeadmin.git' 

HTH.

Wenn jemand eine einfachere Methode hat, bitte teilen!

Verwandte Themen