按create_at或updated_at(以较新者为准)排序Ruby on Rails

时间:2014-12-16 01:49:28

标签: ruby-on-rails ruby rails-activerecord

我感觉这是一个简单的问题,除了我似乎无法找到答案。

我有一组记录:

@mymonkeys = @user.monkeys.all

我需要的是最近与之交互的3只猴子(创建或更新)。

我可以像这样获得最近创建的猴子: @mymonkeys.sort_by(&:created_at).reverse!.take(3)

最近更新过的猴子是这样的: @mymonkeys.sort_by(&:updated_at).reverse!.take(3)

但是有一行代码可以返回最近创建或更新过的猴子吗?

非常感谢!



PS: 我看见 this question提到了coalesce关键字,但我无法确定这是否是我正在寻找的内容。

2 个答案:

答案 0 :(得分:3)

&:created_at{ |monkey| moneky.created_at }的语法糖。通过你想做的事情。

@mymonkeys.sort_by { |m| [m.created_at, m.updated_at].max }.reverse!.take(3)

答案 1 :(得分:1)

您可以(也可能应该)在数据库中执行此操作,但COALESCE不是您正在寻找的。 COALESCE用于将NULL转换为SQL中的其他内容,您可以这样说:

coalesce(might_be_null, what_i_want_instead_of_null)

在您的情况下,您应始终同时拥有created_atupdated_at,这样您就不必担心NULL。

如果要选择多个值中的最大值,则需要使用GREATEST;如果你想要最小的,那么使用LEAST;任何值得用于实际工作的数据库都应支持GREATEST和LEAST,但如果需要,可以使用CASE伪造它。最近的时间戳是最好的,所以你要对greatest(created_at, update_at)进行排序;你还想要最近的三个在列表的顶部,所以你想要一个降序排序(即最大的第一个);您可以在数据库中发送LIMIT 3。这给了你:

three_recent_monkeys = @user.monkeys.order('greatest(created_at, updated_at) desc').limit(3)

这是Rails,因此updated_at应始终至少为created_at,因此greatest(created_at, updated_at)应始终为updated_at。这意味着你可以简化一些事情,然后说:

three_recent_monkeys = @user.monkeys.order('updated_at desc').limit(3)