2016-04-09 16 views
0

So habe ich eine API, die ich abfragen und eine Ergebnisliste zurückgeben kann. Meine App verarbeitet dann die Ergebnisse in ActiveRecord wie Objekte in einem Array. Ich zeige diese Objekte in einer Ansicht in ihrer Gesamtheit an, aber ich möchte auch die Ergebnisse filtern.Filtern eines Nicht-Active-Records-Modells auf die richtige Weise

Was ist der beste Weg, dies zu tun?

Derzeit mache ich etwas wie folgt aus:

Ansicht

= form_tag path(resource), method: :get, class: "form-inline", role: "form" do 
.col-sm-3 
    = label_tag "See unlimited usage only?" 
    .clearfix 
    = select_tag "usage", options_for_select(resource.class::USAGE, params[:usage]), class: "form-control", prompt: "All usage limits" 

Controller

def show 
    @media_deals = resource.media_deals 
    if params[:usage].present? 
    filter = params[:usage] 
    if filter == "unlimited" 
     @media_deals = @media_deals.find_all{|d| d.download_limit_display.casecmp("Unlimited") == 0} 
    elsif filter == "limited" 
     @media_deals = @media_deals.find_all{|d| d.download_limit_display.casecmp("Unlimited") != 0} 
    end 
    end 
end 

Beachten Sie, dass es wird mehr als ein Filter sein, nicht nur der eine gezeigt.

Antwort

0

Nun, bis jetzt machst du ziemlich gut, es ist nichts falsch daran, es so zu machen, aber ich habe ein paar Vorschläge, wie man es besser machen kann. Zunächst, vor allem, wenn Sie mehrere Filter verwenden möchten, organisieren Sie sie in Proc s. Wie dies zum Beispiel:

{ 
    unlimited: Proc.new {|d| d.download_limit_display.casecmp("Unlimited") == 0}, 
    limited: Proc.new {|d| d.download_limit_display.casecmp("Unlimited") != 0} 
} 

Auf diese Weise können alle Filter an einem Ort zu bringen und sammeln sie je nach Wich, die Sie brauchen, und dann gehen mit einem each Schleife wie folgt aus:

filters.each {|filter| @media_deals.find_all! &filter} 

UPDATE

OK, also für den vollen Zyklus. So könnte Ihre Ansicht aussehen.

= form_tag path(resource), method: :get, class: "form-inline", role: "form" do 
    .col-sm-3 
    = label_tag "See unlimited usage only?" 
    .clearfix 
    = select_tag "filters[usage]", options_for_select(resource.class::USAGE, params[:filters][:usage] if params[:filters].present?)), class: "form-control", prompt: "All usage limits" 
    .col-sm-3 
    = label_tag "Filter by date" 
    .clearfix 
    = select_tag "filters[usage]", options_for_select(resource.class::USAGE, params[:filters][:usage] if params[:filters].present?)), class: "form-control", prompt: "All dates" 

Und hier ist Ihr Controller.

def show 
    @media_deals = resource.media_deals 
    filters.each {|filter| @media_deals.select! &filter} if params[:filters].present? 
end 

private 

def all_filters 
    { 
    unlimited: Proc.new {|d| d.download_limit_display.casecmp("Unlimited") == 0}, 
    limited: Proc.new {|d| d.download_limit_display.casecmp("Unlimited") != 0}, 
    newest: Proc.new {|d| d.created_at <= 1.day.ago }, 
    recent: Proc.new {|d| d.created_at <= 4.days.ago }, 
    oldest: Proc.new {|d| d.created_at > 1.year.ago } 
    } 
end 

def filters 
    params[:filters].values.map {|f| all_filters[f] if f}.select &:present? 
end 

Nur um Ihnen einen Sinn dessen zu geben, was vor sich geht. Ich würde vorschlagen, einen Schritt weiter zu gehen und diese Filtergruppe (die all_filters-Methode) auf die Ressource selbst zu verschieben und sie vielleicht in einen Hash von Hashes aufzuteilen, wenn die Benennung unordentlich wird.

+0

Können Sie ein Beispiel geben, wie dies von Ansicht zu Controller bitte umgesetzt werden würde? – Robbo

+0

@Robbo, ich aktualisierte die Antwort – Almaron

+0

Danke. Ich werde es versuchen – Robbo

Verwandte Themen