【发布时间】:2017-03-08 06:48:24
【问题描述】:
背景:
我有 Product 模型,其中包括 4 个类别
class Product < ActiveRecord::Base
enum category: [:recent, :cheapest, :most_expensive, :popular]
end
我已经为每个带有分页的类别 (LIMIT 10) 实现了一个自定义 ORDER BY,所以当我获取产品列表时,我会在每个查询中获得多个 SQL 查询,其中 ORDER BY 不同,例如这个:
最近:
SELECT "products".* FROM "products" ORDER BY "products"."created_at" DESC LIMIT 10
最便宜的:SELECT "products".* FROM "products" ORDER BY "products"."price" ASC LIMIT 10
最昂贵的: SELECT "products".* FROM "products" ORDER BY "products"."price" DESC LIMIT 10
受欢迎: SELECT "products".* FROM "products" ORDER BY "products"."popularity" DESC, "products"."created_at" DESC LIMIT 10
如上所述,上述每个查询的结果是 Product::ActiveRecord_Relation 包含 10 个产品,每个查询具有不同的顺序。
问题:
我已将新列添加到 Product 模型,它是带有布尔值的 featured,我需要在每个查询的开头应用 ORDER BY featured DESC,同时保持其他 ORDER BY 字段不变(即流行的查询应该是这样的SELECT "products".* FROM "products" ORDER BY "products"."featured" DESC, "products"."popularity" DESC, "products"."created_at" DESC LIMIT 10)。
注意: ORDER BY featured DESC 只是附加在前面的ORDER BY 语句的开头,它应用于子集而不是整个模型。
我尝试了什么?
我尝试了以下场景:
- 在控制器中添加
@products = @products.order(featured: :desc),但结果与预期不符,因为它将订单添加到现有订单链的末尾。 - 在产品模型
default_scope { order(featured: :desc) }中使用default_scope,但结果不是预期的,因为它在整个模型上实现了订单,但预期的结果是仅对子集(10条记录)应用订单。 - 在控制器
@products = @products.reorder('').order(featured: :desc)中使用reorder,但结果仍然不如预期,因为这删除了旧订单,实际上我需要保留它,但在ORDER BY链的末尾
我能做的唯一解决方案是使用字符串变量按链保存先前的订单,然后使用reorder('').order(featured: :desc),最后将字符串附加到新ORDER BY的末尾:
current_order = @products.to_sql[@products.to_sql.downcase.index('order by')+8..@products.to_sql.downcase.index('limit')-1]
@products = @products.reorder("featured desc, #{current_order}" )
但我确信有更好的解决方案需要您的支持才能实现。
总结:
正如下面的 cmets 中总结的,我需要以下实现:
仅给定r 其中r = M.order(:a),我想运行r.something(:b) 并获得M.order(:b).order(:a) 的效果,而不是r.order(:b) 会给你的M.order(:a).order(:b)
【问题讨论】:
-
所以只给
r哪里r = M.order(:a)你想说r.something(:b)并得到M.order(:b).order(:a)的效果而不是M.order(:a).order(:b)r.order(:b)会给你的效果,对吧? -
由于只有 10 条记录,您也可以在 Ruby 中使用
@products.sort_by(&:featured)对它们进行排序,或者我是否误解了您想要的输出。 -
@Iceman
sort_by结果是数组,我期待ActiveRecord_Relation和sort_by不适用于boolean -
啊,好吧,只是一个想法,没有很好地阅读您的问题。
标签: ruby-on-rails ruby activerecord sql-order-by rails-activerecord