Sql 将activerecord查询的循环减少为一个查询
我有一个列表模型,它有一个category列和size列。对于每个类别,我都有一个大小数组。我只想返回每个类别中与大小数组相对应的列表。(我还有一个设计器数组作为params[:designer]的条件。) 参数散列:Sql 将activerecord查询的循环减少为一个查询,sql,ruby-on-rails,activerecord,Sql,Ruby On Rails,Activerecord,我有一个列表模型,它有一个category列和size列。对于每个类别,我都有一个大小数组。我只想返回每个类别中与大小数组相对应的列表。(我还有一个设计器数组作为params[:designer]的条件。) 参数散列: params[:category] => ['tops', 'bottoms', 'outerwear', 'footwear'] params['tops'] => ['M', 'L'] params['bottoms'] => [] params['oute
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调用)对其进行分页。将其转换为in查询:
Listing.where(designer: params[:designer]).where("category IN (?)", params[:category])
更新:
似乎上面的代码不是op想要的,所以我做了一些修改。如果我理解正确,您需要生成一个包含大量ORs的大查询。你不用去阿雷尔也可以做到:
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)
它生成此查询(分页前):
您可以将数组传递到
,其中:
@listings = Listing.where(category: params[:category], s...
我最后用了阿雷尔,这很不错。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('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)
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)