0

在我的用户模型中,我有一个范围:

scope :with_tournament_entrees, :include => :registers, :conditions => "registers.id IS NOT NULL"

我想看看这个范围生成的 SQL 并产生:

"SELECT \"users\".* FROM \"users\"  WHERE (registers.id IS NOT NULL)"

我没有看到任何提及我添加的包含参数,如果在控制台中作为原始 SQL 在ActiveRecord::Base.connection.execute. 另一方面,如果我要在控制台中查询 User.with_tournament_entrees ,它会产生我需要的正确的8 条记录,没有任何错误,查看日志我看到正在执行的 SQL 语句......

SELECT "users"."id" AS t0_r0, "users"."email" AS t0_r1, 
       "users"."encrypted_password" AS t0_r2, ....
       "registers"."id" AS t1_r0, "registers"."competition_id" AS t1_r1,
       "registers"."user_id" AS t1_r2 ... 
       FROM "users" LEFT OUTER JOIN "registers" ON "registers"."user_id" = "users"."id"
       WHERE (registers.id IS NOT NULL)

这看起来是正确的,所以只是为了仔细检查,我复制了 SQL 并将其包装在里面ActiveRecord::Base.connection.execute,它执行得很好——除了现在而不是像我调用范围时那样得到8 条记录,而是得到12 条记录

是什么赋予了?它正在执行完全相同的 SQL 对吗?那么为什么我会得到不同的结果呢?我正在使用 PostgreSQL 数据库。

哦,我知道你不应该在 Rails 3 中使用范围,这就是为什么我要尝试使用 SQL,以便弄清楚如何 ActiveRecordify(?) 它。

4

1 回答 1

1

这可以通过 2 个事实来解释: 1. 有效地添加连接意味着您可以根据用户行和寄存器行的每个有效组合获得一个结果集行。因此,如果某个用户在寄存器表中有 2 条记录 - 您将获得该用户记录的两行。2. Active Record 知道上述内容并且能够“合并”行,这样你就可以得到一个用户有两个寄存器,而不是两个相同的用户每个有一个寄存器。

这样,从 MySQL 的角度来看,运行裸查询会产生 12 行的结果。ActiveRecord 将它们处理到 8 条记录,因为有些行包含相同的用户字段,只是多个寄存器的字段。

希望这可以帮助 :)

于 2012-11-09T02:00:27.833 回答