加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – 在ActiveRecord子集上更改’ORDER BY’链

发布时间:2020-12-17 02:09:47 所属栏目:百科 来源:网络整理
导读:背景: 我有产品型号,包括4个类别 class Product ActiveRecord::Base enum category: [:recent,:cheapest,:most_expensive,:popular]end 我已经为每个带分页的类别(LIMIT 10)实现了一个自定义ORDER BY,所以当我得到产品列表时,我在每个查询中得到多个具有不
背景:

我有产品型号,包括4个类别

class Product < ActiveRecord::Base
  enum category: [:recent,:cheapest,:most_expensive,:popular]
end

我已经为每个带分页的类别(LIMIT 10)实现了一个自定义ORDER BY,所以当我得到产品列表时,我在每个查询中得到多个具有不同ORDER BY的SQL查询,如下所示:

最近:
SELECT“products”.* FROM“products”ORDER BY“products”.“created_at”DESC LIMIT 10

最便宜的:选择“产品”.*从“产品”订购“产品”.“价格”ASC限制10

most_expensive:SELECT“products”.* FROM“products”ORDER BY“products”.“price”DESC LIMIT 10

流行:SELECT“产品”.* FROM“产品”ORDER BY“产品”.“流行度”DESC,“产品”.“created_at”DESC LIMIT 10

如上所述,每个上述查询,结果Product :: ActiveRecord_Relation包含10个产品,每个查询的顺序不同.

题:

我在Product模型中添加了一个新的列,它具有布尔值,我需要在每个查询开始时应用ORDER BY特色DESC,同时保持其他ORDER BY字段(即流行查询应该像这样SELECT “产品”.*来自“产品”ORDER BY“产品”.“特色”DESC,“产品”.“人气”DESC,“产品”.“created_at”DESC LIMIT 10).

注意:ORDER BY特色DESC仅附加在前一个ORDER BY语句的开头,并且它应用于不在整个模型上的子集.

我试过了什么?

我尝试了以下方案:

>在控制器中添加@products = @ products.order(features :: desc),但结果不符合预期,因为它按顺序将订单添加到现有订单的末尾.
>在产品型号default_scope {order(features :: desc)}中使用default_scope,因为它实现了整个模型的顺序,但预期结果仅在子集上应用了顺序(10条记录).
>在控制器中使用重新排序@products = @ products.reorder(”).order(featured :: desc)但结果仍然不如预期,因为这删除了旧订单,实际上我需要保留它但是在结束时ORDER BY链

我能做的唯一解决方案是使用字符串变量按链保存先前的顺序,然后使用重新排序(”).order(特色:: 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}" )

但我确信有一个更好的解决方案,我需要你的支持来实现它.

解决方法

你有没有在这里使用范围链的原因?这似乎是一个使用它的完美案例.枚举的使用也不清楚.

像这样的东西:

# /app/models/product.rb
class Product < ActiveRecord::Base
 scope :recent,{ order(created_at: :desc) }
 scope :cheapest,{ order(price: :asc) }
 scope :most_expensive,{ order(price: :desc) }
 scope :popular,{ order(popularity: :desc) }
 scope :featured,{ where(featured: true) }
end

然后在你的控制器中你可以做到:

# /app/controllers/products_controller.rb
...
Product.featured.cheapest.limit(10)
Product.featured.most_expensive.limit(10)
...

等等.

AREL应该正确构建查询,如果您希望以不同的方式应用,IIRC可以交换范围的序列(例如,在最便宜之后显示).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读