2016-07-28 16 views
0

ich eine aktuelle Implementierung, die mir meine Suchergebnisse nach Kategorien NameSuche Funktionalität Schienen 4

class Category < ActiveRecord::Base 
    has_many :bike_categories 
    has_many :bikes, through: :bike_categories 
end 

class BikeCategory < ActiveRecord::Base 
    # Holds bike_id and category_id to allow multiple categories to be saved per image, as opposed to storing an array of objects in one DB column 
    belongs_to :bike 
    belongs_to :category 
end 

class Bike < ActiveRecord::Base 
    has_many :bike_categories, dependent: :destroy 
    has_many :categories, through: :bike_categories 
end 

Model 

def self.search(params) 
    includes_categories(params[:name]) 
end 

def self.includes_categories(category_names) 
    joins(:categories) 
    .where(categories: { name: category_names }) 
    .group('bikes.id') 
    .having("count(*) = ?", category_names.size) 
end 

So filtern können, wenn ich die folgenden Daten haben

Bike 
id: 1 title: 'Bike 1' 
id: 2 title: 'Bike 2' 

category 
id: 1 name: 'Mens' 
id: 2 name: 'Womens' 
id: 3 name: 'Mountain Bike' 
id: 4 name: 'Hybrid' 

bike_categories 
id: 1 bike_id: 1 :category_id: 2 # Womens, Mountain Bike 
id: 2 bike_id: 1 :category_id: 3 

id: 3 bike_id: 2 :category_id: 2 # Womens, Hybrid 
id: 4 bike_id: 2 :category_id: 4 

In meinem Filter, wenn ich wählen Womens und Mountain Bikes ich bekomme alle Bikes mit den Kategorien Womens, Mountain Bikes, also in diesem Beispiel nur das eine Ergebnis.

Allerdings würde ich dann noch einen Schritt weiter gehen und eine andere Kategorie wählen, hybrid (so würde ich Filter wählen Womens, Mountain Bikes, Hybrid) und würde alle Fahrräder mögen, die entweder Womens, Mountain Bikes und Womens, Hybrid haben, so in diesem Fall sollte ich die 2 Ergebnisse erhalten zurückgegeben

Wie könnte ich diese Abfrage ändern, um dies zu ermöglichen?

Dank

+0

zu ermöglichen, ich denke, Sie Ihre Anfrage wird wieder finden werden Fahrräder, die entweder „Frauen-Bikes“ sind oder "mountian bikes" - da du nur kategorien in den testdaten gegen bike 1 hast, kann jede frage nur ein bike zurückgeben - versuche mal ein mountian bike und einen frauen hybrid zu deinen testdaten hinzuzufügen und schau was passiert –

+0

entschuldigung, es gab einen typo da, habe die Frage aktualisiert. wenn ich 3 Filterparameter wähle, erhalte ich keine Resultate – Richlewis

+0

Ich denke, dass Sie es in zwei Attribute teilen mussten, um zu erhalten, was Sie wünschen - Geschlecht (Männer | Frauen) und bike_type (mountian Fahrrad | hybrid) –

Antwort

0

ich etwas entlang der folgenden Zeilen verwendet Filterung von Suchergebnissen durch mehrere Attribute

# style for Mountian Bike etc. 
class Style < ActiveRecord::Base 
    has_many :bike_styles 
    has_many :bikes, through: :bike_styles 
end 

class BikeStyle < ActiveRecord::Base 
    belongs_to :bike 
    belongs_to :style 
end 

# gender for Womens, Mens etc. 
# (or maybe there is a better name if you have girls/boys as well) 
class Gender < ActiveRecord::Base 
    has_many :bike_genders 
    has_many :bikes, through: :bike_genders 
end 

class BikeGender < ActiveRecord::Base 
    belongs_to :bike 
    belongs_to :gender 
end 

class Bike < ActiveRecord::Base 
    has_many :bike_styles, dependent: :destroy 
    has_many :styles, through: :bike_styles 

    has_many :bike_genders, dependent: :destroy 
    has_many :genders, through: :bike_genders 

    # repeat for other searchable attributes (e.g. frame size) 
    # has_many :bike_sizes, dependent: :destroy 
    # has_many :sizes, through: :bike_sizes 

    # returns filtered results based on the params, call as follows: 
    # Bikes.search style: "Mountian Bike", gender: "Mens"  
    # Bikes.search style: "Mountian Bike" 
    # Bikes.search gender: "Mens" 
    def self.search(params) 
    filtered = params[:collection] || self 
    filtered = style_filter(filtered, params[:style]) 
    filtered = gender_filter(filtered, params[:gender]) 
    filtered 
    end 

    # filters by style (if one is provided) 
    def self.style_filter(filtered, style) 
    filtered = filtered.joins(:styles).where(styles: {name: style}) unless style.blank? 
    filtered 
    end 

    # filters by gender (if one is provided) 
    def self.gender_filter(filtered, gender) 
    filtered = filtered.joins(:genders).where(genders: {name: gender}) unless gender.blank? 
    filtered 
    end 
end 
+0

Vielen Dank Ian, dass er sich die Zeit genommen hat, das aufzuschreiben, gibt mir etwas, auf das ich mich beziehen kann und von dem ich lernen kann. Wenn ich die Params zur Suchmethode übergebe, werden sie einfach als ein Array '[' Mens ',' Mountain Bikes ',' Hybrid '] 'zum Beispiel – Richlewis

+0

oder sende ich einen Hash ein? – Richlewis

+0

params wäre ein Hash zum Beispiel: '{gender:" mens ", style: [" Hybrid "," Mountian Bike "]}' - Sie müssten nur die Schlüssel eingeben, die Sie filtern wollten –