我有一个使用acts_as_rateable
插件的rails应用程序。
我一直在想弄清楚如何使用这个插件检索未评级的模型 - 但这更像是一个常见的rails / SQL问题,而不是特定于这个插件。
作为有价物的行为会将以下内容添加到架构中:
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
所以我想要类似下面的伪代码
Review.find(:all, :conditions=>"not rated by anyone")
Review.find(:all, :conditions=>"not rated by anyone except review.user")
但是我无法弄清楚SQL是如何做到这一点的,也不是用于生成SQL的rails魔法: - )
更新:此查询似乎找到除拥有该模型的用户以外的其他人评定的所有模型。所以我想我只需要以某种方式反转它。
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 :(得分:1)
命名范围是解决此问题的方法。我会在您的Review
模型中添加两个命名范围。类似的东西:
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。
编辑:第二次尝试
是的,让我们再来吧!其中一个问题是那里有多个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)
答案 1 :(得分:0)
我有一些方法使用这样的查询:
Review.find(:all,
:joins=>'left outer join ratings on reviews.id=ratings.rateable_id && ratings.rateable_type="Review"',
:conditions=>'ratings.rating is NULL')
这看起来它会返回所有没有评级的评论模型。
我认为这个正在努力查找创建评论的用户未评级的所有评论模型:
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')