如何使活动记录连接返回唯一对象?

问题描述:

我有一个简单的查询需求:查找自2013年1月1日以来订购的用户列表。如何使活动记录连接返回唯一对象?

在SQL中,这是一个非常简单的查询。

但我使用的是Rails和Active Record。

所以我写了:User.joins(:orders).where("orders.created_at >= '2013-01-01 00:00:00'")

在我们的数据库,我们必须通过75个用户自2013年1月1日取得100个订单。 (有些用户明显地做出了多个订单)。

但是,上述表达式返回100个用户。 (必须有重复。)

我试图User.joins(:orders).where("orders.created_at >= '2013-01-01 00:00:00'").uniq

,不能正常工作。

如何获得自2013年1月1日以来订购的75位用户?

+2

如果你试图链'选择( “DISTINCT(users.id)”)'或'组(“users.id”)' – 2013-03-05 17:53:00

+0

您在'User'和'Order'模型中定义了关系吗?没有必要使用原生sql – ant 2013-03-05 17:58:50

+0

是的,我在User和Order模型之间建立了关系。 – 2013-03-05 18:03:03

@dbjohn有正确的想法,但我认为你想避免创建额外的对象。这里有他的解决方案有轻微变形,让数据库做的uniq-ING为您提供:

date = "2013-01-01 00:00:00" 
User.joins(:orders).where("orders.created_at >= ?", date).distinct 

请注意,您可以重新排列的方法,以适应任何你认为最语义和ActiveRecord的会写相同SQL为你。

User.joins(:orders). 
    where("orders.created_at >= '2013-01-01 00:00:00'"). 
    group('users.id') 

group方法将链接到查询并为您提供唯一记录列表。

Rails的,因为3.2.1版本 增加了uniq所以现在你可以使用uniq

http://apidock.com/rails/ActiveRecord/QueryMethods/uniq

+0

这与'distinct'不同,它使用SQL来从5.1.1开始,缩小了防止重复记录被实例化的范围。 – aceofspades 2017-06-12 18:26:50