【发布时间】:2014-11-05 19:39:04
【问题描述】:
我有一个用户模型和一个卡片模型。用户有很多卡片,所以卡片有一个属性user_id。
我想为每个用户获取最新的单张卡片。我已经能够做到这一点:
Card.all.order(:user_id, :created_at)
# => gives me all the Cards, sorted by user_id then by created_at
这让我走到了一半,我当然可以遍历这些行并抓住每个用户的第一个。但这对我来说真的很糟糕,因为我会在 Ruby 中使用数组来做很多这样的事情。
我也可以这样做:
Card.select('user_id, max(created_at)').group('user_id')
# => gives me user_id and created_at
...但我只取回 user_ids 和 created_at 时间戳。我无法选择任何其他列(包括 id),所以我得到的东西毫无价值。我也不明白为什么 PG 不允许我选择比上面更多的列而不将它们放入 group_by 或聚合函数中。
我更愿意找到一种仅使用 ActiveRecord 来获得我想要的东西的方法。我也愿意用原始 SQL 编写这个查询,但前提是我不能用 AR 完成它。顺便说一句,我使用的是 Postgres DB,这限制了我的一些选择。
谢谢大家。
【问题讨论】:
-
Card.all.order(:user_id, :created_at).first或Card.all.order(:user_id).order(:created_at).first怎么样 -
@Bala 我希望为所有制作卡片的用户每个用户提供最新的卡片。这只会给我最低 ID 且至少有一张卡的用户的最新卡。
-
哪一个给了你最低的ID?只需将
:desc添加到:created_at -
我很确定这是 AR ORM 功能不足的情况之一,您需要转至
find_by_sql。有关所需的 SQL,请参阅 stackoverflow.com/questions/1313120/… 及其副本。我遇到了一个相关的问题,最终需要维护一个“最后一条记录”ID 表以使查询足够快(尽管我需要最后一个 K,而不是最后一个 1)。您可以在链接的讨论中看到,对于一百万条记录,查询需要几分钟时间。 -
@Bala 这仍然只会返回我一条记录。如果我有 10 个用户,并且每个用户至少制作了 1 张卡,我想为每个用户获取最新的卡。所以查询应该返回 10 张卡片,而不是 1 张。
标签: ruby-on-rails ruby postgresql activerecord ruby-on-rails-4