我有一个列表模型,它有一个类别列和大小列。对于每个类别,我都有一系列大小。我想只返回每个类别中与大小数组对应的列表。 (我也有一系列设计师作为params [:designer]的条件。)
Params hash:
params[:category] => ['tops', 'bottoms', 'outerwear', 'footwear']
params['tops'] => ['M', 'L']
params['bottoms'] => []
params['outerwear'] => ['XL']
params['footwear'] => ['11', '12']
我创建了一个循环来执行此操作:
@listings = []
params[:category].each do |category|
@listings += Listing.where(category: category, size: params[category], designer: params[:designer], sold: nil).includes(:photos).page(params[:category_page]).per(@perpage)
end
但我需要将它全部放在一个查询中,因为我正在使用kaminari gem(.page调用)对其进行分页。
答案 0 :(得分:1)
您可以将数组传递给where
:
@listings = Listing.where(category: params[:category], s...
答案 1 :(得分:1)
我最终使用了非常好的Arel。 Arel允许您构建所需的任何查询,然后在Model.where()上调用它。它有点复杂但是我找到的唯一解决方案。
t = Listing.arel_table
query = t[:category].eq('rooney')
params[:category].each do |category|
if params[category]
params[category].each do |size|
query = query.or(t[:category].eq(category).and(t[:size].eq(size)))
end
end
end
dquery = t[:designer].eq('rooney')
params[:designer].each do |designer|
dquery = dquery.or(t[:designer].eq(designer))
end
query = query.and(dquery)
@listings = Listing.where(query).includes(:photos).page(params[:category_page]).per(@perpage)
编辑:
可以使用.eq_any()简化设计器查询。
t = Listing.arel_table
query = t[:category].eq('rooney')
params[:category].each do |category|
if params[category]
params[category].each do |size|
query = query.or(t[:category].eq(category).and(t[:size].eq(size)))
end
end
end
dquery = t[:designer].eq_any(params[:designer])
query = query.and(dquery)
@listings = Listing.where(query).includes(:photos).page(params[:category_page]).per(@perpage)
答案 2 :(得分:0)
将其转换为IN查询:
Listing.where(designer: params[:designer]).where("category IN (?)", params[:category])
更新
上面的代码似乎并不是我想要的,所以我改了一下。如果我理解正确,你需要生成一个包含大量OR的大查询。你可以做到这一点,而无需去参加:
params[:category] = ['tops', 'bottoms', 'outerwear', 'footwear']
params['tops'] = ['M', 'L']
params['bottoms'] = []
params['outerwear'] = ['XL']
params['footwear'] = ['11', '12']
query = params[:category].map do |category|
str = "(category = ?"
str += " AND size IN (?)" if params[category].any?
str += ")"
str
end
scope = Listing.where(query.join(" OR "), *params[:category].map { |cat| [cat, params[cat].any? ? params[cat] : nil] }.flatten(1).compact)
scope = scope.where(designer: params[:designer], sold: nil)
scope = scope.page(params[:per_page]).per(@page)
它生成此查询(在分页之前):
2.0.0-p247 :095 > scope.to_sql
=> "SELECT \"listings\".* FROM \"listings\" WHERE \"listings\".\"designer\" IS NULL AND \"listings\".\"sold\" IS NULL AND ((category = 'tops' AND size IN ('M','L')) OR (category = 'bottoms') OR (category = 'outerwear' AND size IN ('XL')) OR (category = 'footwear' AND size IN ('11','12')))"