我有一个当前的实现,允许我按类别名称
过滤我的搜索结果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
所以,如果我有以下数据
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
在我的过滤条件中,如果我选择Womens
和Mountain Bikes
,我会获得所有类别为Womens, Mountain Bikes
的自行车,因此在此示例中仅显示一个结果。
然而,我希望更进一步,选择另一个类别,hybrid
(所以我会选择过滤器Womens, Mountain Bikes, Hybrid
),并希望所有自行车都有Womens, Mountain Bikes
和{ {1}},所以在这个例子中我应该得到2个结果返回
我如何修改此查询以允许此操作?
由于
答案 0 :(得分:0)
我使用了以下几行中的内容来允许按多个属性过滤搜索结果
# 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