Ruby on Rails:如何使用ActiveRecord对两列进行排序?


91

我想按两列排序,一列是DateTime(updated_at),另一列是Decimal(Price)

我希望能够先按updated_at排序,然后,如果同一天发生多个项目,请按价格排序。

Answers:


64

假设您使用的是MySQL,

Model.all(:order => 'DATE(updated_at), price')

请注意与其他答案的区别。该updated_at列将是一个完整的时间戳记,因此,如果要基于更新的日期进行排序,则需要使用一个函数来从时间戳记中仅获取日期部分。在MySQL中,即DATE()


7
要阻止联接随机断开并显示“歧义列”消息,应使用以下更可靠的版本:(:order => ["DATE(#{table_name}.updated_at)", :price]请注意,这:price是一个符号。)
Jo Liss 2012年

我必须这样逃避我的订单栏orderModel.all(:order => "day asc, `order` asc")
授予


56
Thing.find(:all, :order => "updated_at desc, price asc")

会成功的

更新:

Thing.all.order("updated_at DESC, price ASC")

是Rails 3要走的路。(感谢@cpursley


4
谢谢@Erik-我知道这个答案很旧,所以这是现在警告那些人的警告:从Rails 3.2开始不推荐使用此方法。使用Thing.all代替=)
Abdo

正确,这对我来说很有效: Thing.all.order("updated_at DESC, price ASC")
cpursley

1
当我需要小写排序的值时,您的更新对我很有帮助:Thing.order("LOWER(name), number")
尼克,

36

Active Record查询接口使您可以指定要订购查询的属性数量

models = Model.order(:date, :hour, price: :desc)

或者,如果您想获得更具体的信息(感谢@ zw963):

models = Model.order(price: :desc, date: :desc, price: :asc) 

奖励:在第一个查询之后,您可以链接其他查询:

models = models.where('date >= :date', date: Time.current.to_date)

我知道这是一个旧帖子,但是我个人将更model改为,models以便一个人知道它是多元的。只是一个建议。
塔斯(Tass)2016年

1
我认为应该编辑一个更特别的示例:例如,models = Model.order({price::desc},{date::desc},{price:asc})
zw963

如果有人将其粘贴并看到未定义的方法错误,则这里有一个小错字。应该:asc改为ascModel.order({price: :desc}, {date: :desc}, {price: :asc})
nayiaw

18

实际上,有许多方法可以使用Active Record来实现。上面没有提到的一种(多种格式,都有效):

Model.order(foo: :asc).order(:bar => :desc).order(:etc)

也许它更冗长,但我个人认为它更易于管理。SQL仅一步生成:

SELECT "models".* FROM "models" ORDER BY "models"."etc" ASC, "models"."bar" DESC, "models"."foo" ASC

因此,对于原始问题:

Model.order(:updated_at).order(:price)

您无需声明数据类型,ActiveRecord可以轻松做到这一点,您的DB Engine也可以做到这一点


当使用来自两个不同表的两列时,这非常有用:Member.includes(:voter).order(“ town_club asc”)。order(“ voters.last_name asc”)
bkunzi01 '16

1
您发布的SQL是否对应Model.order(foo: :asc).order(:bar => :desc).order(:etc)?SQL中的order子句的顺序与运行该语句时的顺序相反.to_sql
加兹

1
@Qaz这是很久以前了。我想我可能需要更正此错误,我从未注意到。我待会再检查。谢谢。
Ruby Racer,


0

这些都不对我有用!经过整整两天的互联网搜寻,我找到了解决方案!

假设您在产品表中有很多列,包括:special_price和msrp。这是我们试图进行排序的两列。

好的,首先在模型中添加以下行:

named_scope :sorted_by_special_price_asc_msrp_asc, { :order => 'special_price asc,msrp asc' }

其次,在产品控制器中,添加您需要执行搜索的位置:

@search = Product.sorted_by_special_price_asc_msrp_asc.search(search_params)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.