少し苦労していた、かなり複雑なレコードの並べ替えをしようとしています。私は3つのモデルを持っています:
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
これにより、返されたユーザーを単純にループし、次のように個々のレコードをクエリして、各ユーザーの " Total Wins "を取得できます。
user.results.where("win = true").count()
ただし、これをさらに一歩進めて、すべてのユーザーを「合計勝利数」で並べ替えたいと思います。これが私が思いつく最高のものです。
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 データベースを使用しています。
編集:
実際には 3 つの選択が行われます。最初の選択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
、クエリが続く場合、これは問題ではありません。