私はFact
モデルを持っていhas_many
:votes
ます。投票にもuser_id
フィールドがあります。モデルのスコープで次のことを表現したいと思います。Xに等しいFact
0票のすべてのファクトを教えてください。user_id
私はこれにどのように取り組むかを理解するのに十分なほどアレルに精通していません。アイデア?
私はFact
モデルを持っていhas_many
:votes
ます。投票にもuser_id
フィールドがあります。モデルのスコープで次のことを表現したいと思います。Xに等しいFact
0票のすべてのファクトを教えてください。user_id
私はこれにどのように取り組むかを理解するのに十分なほどアレルに精通していません。アイデア?
これは機能します:
class Fact < ActiveRecord::Base
scope :by_user, lambda { |id| joins(:user).where('users.id == ?', id).readonly(false) }
scope :vote_count, lambda { |count| where('? == (select count(fact_id) from votes where votes.fact_id == facts.id)', count)}
end
Fact.by_user(1).vote_count(0)
vote_countスコープは少しsqlyですが、これらのファインダーを好きなようにチェーンできます。また、基になるsqlを次のように表示することもできます。
Fact.by_user(1).vote_count(0).to_sql
そしてあなたのコメントに加えて、あなたは最初に関係を宣言することによって純粋なアレルで同じことをするかもしれません:
f = Arel::Table.new(:facts)
v = Arel::Table.new(:votes)
u = Arel::Table.new(:users)
次に、クエリを作成してsqlにレンダリングします。
sql = f.join(u).on(f[:user_id].eq(1)).where('0 == (select count(fact_id) from votes where votes.fact_id == facts.id)').to_sql
演算子を使用して列を操作できます。 f[:user_id].eq(1)
次にそれを使用します:
Fact.find_by_sql(sql)
よりエレガントな構文を取得するためにできることはもっとたくさんあると確信しています('where 0 == ...'なし)。また、Rails3スコープは舞台裏でArelを使用していると確信しています-http: //m.onkey.org/active-record-query-interface
私は次のスコープでこの問題を解決することになりました:
scope :not_voted_on_by_user, lambda {|user_id| select("distinct `facts`.*").joins("LEFT JOIN `votes` ON `facts`.id = `votes`.fact_id").where(["votes.user_id != ? OR votes.user_id IS NULL",user_id])}