Ruby-on-rails 如何让 Active Record join 返回唯一对象?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15230568/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 21:33:15  来源:igfitidea点击:

How to make Active Record join return unique objects?

ruby-on-railsactiverecord

提问by Zack Xu

I have a simple query need: Find a list of users who made an order since Jan 1, 2013.

我有一个简单的查询需求:查找自 2013 年 1 月 1 日起下订单的用户列表。

In SQL, it's a very simple query.

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

But I'm using Rails and Active Record.

但我正在使用 Rails 和 Active Record。

So I wrote: User.joins(:orders).where("orders.created_at >= '2013-01-01 00:00:00'")

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

In our database, we have 100 orders made since 01/01/2013 by 75 users. (Some users made more than one order apparently.)

在我们的数据库中,我们有 75 个用户自 2013 年 1 月 1 日以来下达的 100 个订单。(一些用户显然下了不止一个订单。)

However, the expression above returns 100 users. (There must be duplicates.)

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

I tried User.joins(:orders).where("orders.created_at >= '2013-01-01 00:00:00'").uniq

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

That doesn't work either.

那也行不通。

How can I get the 75 users who've made an order since 01/01/2013?

如何获取自 2013 年 1 月 1 日以来已下订单的 75 位用户?

回答by amcaplan

@dbjohn has the right idea, but I assume you want to avoid creating extra objects. Here's a slight variant on his solution, letting the database do the uniq-ing for you:

@dbjohn 有正确的想法,但我假设您想避免创建额外的对象。这是他的解决方案的一个小变种,让数据库为你做 uniq-ing:

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

Note that you can rearrange the order of methods to fit whatever you think is most semantic, and ActiveRecord will write the same SQL for you.

请注意,您可以重新排列方法的顺序以适合您认为最符合语义的任何内容,ActiveRecord 将为您编写相同的 SQL。

回答by konyak

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

groupmethod will chain to the query and give you a list of unique records.

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

回答by Zack Xu

Rails has added uniqsince version 3.2.1 so now you can use uniq

Railsuniq从 3.2.1 版开始添加,所以现在你可以使用uniq

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

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