Rails 3通过大孩子计数记录

时间:2012-06-20 22:04:47

标签: ruby-on-rails-3 postgresql count sql-order-by grandchild

我正在尝试做一些相当复杂的记录排序,我遇到了一些麻烦。我有三种模式:

    class User < ActiveRecord::Base

    has_many :registers
    has_many :results, :through => :registers

    #Find all the Users that exist as registrants for a tournament
    scope :with_tournament_entrees, :include => :registers, :conditions => "registers.id IS NOT NULL"

end

注册

class Register < ActiveRecord::Base
  belongs_to :user
  has_many :results
end

结果

class Result < ActiveRecord::Base
  belongs_to :register 
end

现在在锦标赛结果页面上,我按其总胜利列出所有用户(胜利是通过结果表计算的)。首先,我找到所有使用查询进入锦标赛的用户:

User.with_tournament_entrees

有了这个,我可以简单地遍历返回的用户并使用以下内容查询每个单独的记录,以检索每个用户“总胜利”:

user.results.where("win = true").count()

但是我还想更进一步,按照“ Total Wins ”对所有用户进行排序,这是我能想到的最好用户:

User.with_tournament_entrees.select('SELECT *, 
                                    (SELECT count(*)  
                                     FROM results 
                                     INNER JOIN "registers" 
                                     ON "results"."register_id" = "registers"."id" 
                                     WHERE "registers"."user_id" = "users.id" 
                                     AND (win = true)
                                    ) AS total_wins 
                                     FROM users ORDER BY total_wins DESC')

我认为它很接近,但实际上并没有按照我强制指示的顺序按 total_wins 排序。我正在使用PostgreSQL数据库。

修改

实际上有三个选择发生,第一个发生在User.with_tournament_entries上,它只对User表执行快速过滤。如果我忽略它并尝试

SELECT *, (SELECT count(*) FROM results INNER JOIN "registers" ON "results"."register_id" = "registers"."id" WHERE "registers"."user_id" = "users.id" AND (win = true)) AS total_wins FROM users ORDER BY total_wins DESC; 

它在PSQL和ERB控制台都失败了。我收到错误消息:

PGError: ERROR: column "users.id" does not exist

我认为发生这种情况是因为内部选择发生在外部选择之前,因此它不能在手边访问用户ID。不确定如何在内部选择发生之前让它访问所有用户ID,但当我User.with_tournament_entires后跟查询时,这不是问题。

1 个答案:

答案 0 :(得分:2)

在你的SQL中,"users.id"引用错误 - 它告诉Postgres寻找一个名为“users.id”的列。

它应该是"users"."id",或者只是users.id(如果您的表/列名称与postgres关键字冲突,或者标点符号或其他异常情况,则只需要引用它) 。