3

私はFactモデルを持っていhas_many :votesます。投票にもuser_idフィールドがあります。モデルのスコープで次のことを表現したいと思います。Xに等しいFact0票のすべてのファクトを教えてください。user_id

私はこれにどのように取り組むかを理解するのに十分なほどアレルに精通していません。アイデア?

4

2 に答える 2

1

これは機能します:

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

于 2010-11-14T19:36:23.013 に答える
1

私は次のスコープでこの問題を解決することになりました:

  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])}
于 2010-11-19T01:29:31.153 に答える