我感觉这是一个简单的问题,除了我似乎无法找到答案。
我有一组记录:
@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
关键字,但我无法确定这是否是我正在寻找的内容。
答案 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_at
和updated_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)