2009-06-12 11 views
0

acts_as_rateableプラグインを使用しているレールアプリケーションがあります。acts_as_rateableで未評価モデルを見つける方法

このプラグインを使用して評価されていないモデルを取得する方法はわかりませんが、これはこのプラグインに固有のものよりも一般的なrails/SQLの質問です。 rateableとして

行為スキーマに以下を追加します。

create_table "ratings", :force => true do |t| 
    t.integer "rating",      :default => 0 
    t.string "rateable_type", :limit => 15, :default => "", :null => false 
    t.integer "rateable_id",     :default => 0, :null => false 
    t.integer "user_id",      :default => 0, :null => false 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    add_index "ratings", ["user_id"], :name => "fk_ratings_user" 

そして、私の定格モデルは、ユーザーID列を持っています。

評価されていない特定のモデルのすべてのインスタンスと、モデルの作成者以外の誰かによって評価されていないすべてのインスタンスを取得できるようにしたいとします。ここで一つのモデルである:

class Review < ActiveRecord::Base 
    acts_as_rateable 

    belongs_to :user 
    ... 
end 

私はそのSQLを生成するために、これを行うためのSQL、またレールの魔法を把握することはできませんしかし、だから私は、次の擬似コード

Review.find(:all, :conditions=>"not rated by anyone") 
Review.find(:all, :conditions=>"not rated by anyone except review.user") 

ような何かをしたいです: - )

更新:このクエリは、モデルを所有するユーザー以外の誰かによって評価されたすべてのモデルを検索しているようです。だから私はこれを何とか逆にする必要があると思う。

Review.find(:all, 
    :joins=>'left join ratings on reviews.id=ratings.rateable_id && ratings.rateable_type="Review"', 
    :conditions=>'reviews.user_id <> ratings.user_id', 
    :group=>'reviews.id') 
+0

はレートがありませんモデルは、ゼロの評価を持っていますか? –

+0

これは可能です。少なくとも、レールインターフェイス(Review.find(1))を使用しているときはそうです。評価== 0そのモデルの評価がない場合は – frankodwyer

答えて

1

名前付きスコープは、この問題を解決する方法です。 Reviewモデルに2つの名前付きスコープを追加します。ような何か:

class Review < ActiveRecord::Base 
    acts_as_rateable 

    belongs_to :user 

    named_scope :not_rated, :conditions => { :rating => 0 } 
    named_scope :not_rated_by_others, 
       :conditions => ["user != ? AND rating == 0", self.user] 
end 

次に、あなたが行うことができます:

@not_rated = Review.not_rated 
@not_rated_by_others = Review.not_rated_by_others 

Railscast that explains named scopesがあります。


EDIT:セカンド

右を試み、の他に行くみましょう!問題の1つは、そこに複数のacts_as_rateableプラグインがあることです。 RubyForgeでthis oneを使ってテストしました。

class Review < ActiveRecord::Base 
    belongs_to :user 

    acts_as_rateable 

    named_scope :not_rated, :select => 'reviews.*', 
       :joins => 'left join ratings on reviews.id = ratings.rateable_id', 
       :conditions => 'ratings.rateable_id is null' 

    named_scope :not_rated_by_others, lambda { |user| { :select => 'reviews.*', 
       :joins => 'left join ratings on reviews.id = ratings.rateable_id', 
       :conditions => ['ratings.user_id != ? and ratings.rateable_id is null', 
       user] }} 
end 

このようにそれを使用します。

frank = User.find_by_name('frank') 
@not_rated = Review.not_rated 
@not_rated_by_others = Review.not_rated_by_others(frank) 
+0

私はnamed_scopeのアイデアが気に入っていますが、残念なことにクエリ自体は「評価」列がないため動作しません。評価プラグインによって計算されたものです。したがって、コンソールReview.find(1).ratingでは動作しますが、SQLでは動作しません。同様に、コンソールのReview.find(1).ratings == []。 – frankodwyer

+0

残念ながら、私はそれをテストする機会がありませんでした。私は今夜​​見ることができるかどうかがわかります。 –

+1

あなたのjoinステートメントにrateable_type = @@ whatever_model_typeを含める必要があります。格付け表がポリモーフィックであるため、結果セット内の他のクラスを返します。 – ErsatzRyan

0

私はこのようなクエリを使用した方法のいくつかを持っている:それはなしですべてのレビューモデルを返すよう

Review.find(:all, 
:joins=>'left outer join ratings on reviews.id=ratings.rateable_id && ratings.rateable_type="Review"', 
    :conditions=>'ratings.rating is NULL') 

これが見えます全く評価しない。

そして、私はこの1つは、レビューを作成したユーザーによって評価されていないすべてのレビューモデルを見つけるために取り組んでいると思う:

Review.find(:all, 
    :joins=>'left outer join ratings on reviews.id=ratings.rateable_id && ratings.rateable_type="Review" && ratings.user_id <> reviews.user_id', 
    :conditions=>'ratings.rating is NULL') 
関連する問題