Acts As Rateable Plugin
Continuing with my work with Ruby on Rails plugins here is my version of the acts_as_rateable plugin. Use this plugin to make your model instances be rated by users. The ratings are numeric and could be from 0 to any number you would like. Typically you can rate articles, posts, reviews, etc from 0 to 5 but this plugin does not dictate the range. To install this plugin run the following command:
script/plugin install http://juixe.com/svn/acts_as_rateable
The installation process will add several ruby files in the vendor/plugins directory. Create a new rails migration and cut and past the following self.up and self.down methods:
def self.up
create_table :ratings, :force => true do |t|
t.column :rating, :integer, :default => 0
t.column :created_at, :datetime, :null => false
t.column :rateable_type, :string, :limit => 15,
:default => "", :null => false
t.column :rateable_id, :integer, :default => 0, :null => false
t.column :user_id, :integer, :default => 0, :null => false
end
add_index :ratings, ["user_id"], :name => "fk_ratings_user"
end
def self.down
drop_table :ratings
end
Once you have the acts_as_rateable plugin installed you can make your ActiveRecord models act as rateable by calling the acts_as_rateable method.
class Post < ActiveRecord::Base acts_as_rateable end
In your controller you can rate a post with just a few lines of code:
post = Post.find(params[:id]) rating = Rating.new(:rating ==> 2, :submitted ==> Time.new) @post.ratings << rating
Similarly you can do this:
post = Post.find(params[:id]) post.add_rating Rating.new(:rating => 2)
And of course you can iterate through the ratings of a post by using the ratings property such as the following bit of code:
post.ratings.each { |r|
logger << "rating value: #{r.rating} for object: #{r.rateable}n"
}
You can also use the ratings property to get the number of ratings this post has been given.
count = post.ratings.size
And if you want to display the average rating you can use the rating function.
average_rating = post.rating
Stay tuned for more on Ruby on Rails plugins…
Technorati Tags: ruby, rails, ruby on rails, plugin, rails plugin, activerecord, acts_as_rateable
















Hi
I used the rateable plugin as well. Many thanks.
Question on the .rating method. How is the performance when you have hundreds of ratings to calculate the average? Any tips on how to make it higher performance?
anand
Hey,
I’m using your rateable plugin, and I would like to filter my results by highest rating. I can’t come up with a way to make it work. Any suggestions.
Zach
I can’t seem to get this to work properly, it’s the first plugin I’ve tried to install so I think my mistake might be something simple I overlooked. Whenever I add “acts_as_rateable” to my story model I get the following error on any action that uses the story model (which is just about all of them): “undefined local variable or method `acts_as_rateable’ for Story:Class”. I installed the plugin and it is present inside the vendor/plugins directory and I created the migration and ran rake on it. If I had to guess it seems like rails isn’t finding the plugin. Is there something else I need to do?
@Sean - I only get that error when I delete the plugin from a Rails application. I just installed the plugin from the SVN repository and it worked right off the bat. In your case, the spelling of the method is correct and you say the plugin is found in the app/vendor/plugins directory. Sorry, but from your description I can’t see what could be the problem. :(
If you wouldn’t mind TechKnow, could you give me an example of a functionality of how I could have the numbers 1..5 or maybe a dropdown to send to a picture for e.g? regarding view/controller programming?
So far I thought of something like this:
def rate
@picture = Picture.find(params[:id])
@picture.add_rating Rating.new(:rating => params[:rating])
end
but I am not really sure what to do in the view, or where to go/modify from here.
Thanks!
Also, regarding the user_id, I’m not sure how to take full advantage of that.
A picture has many users, in the rate method I showed you, how would I set the current rating to be owned by user so and so? I thought something like @picture.user_id = self.current_user.id
would work, but then I realized it’s not for the picture, it’s for the rating, yet rating is being created with calling the model, so not sure. Any tips?
@Daniel - Thanks for your comments. Here are three tutorials you might like… Rails 4-State Ajax & CSS Star Rating by Igvita. Rails Ajax Rating System by Naffis. CSS Star Rating Part Deux by Komodo Media.
Hi, is there any way to make this plugin tally votes numerically instead, like reddit? Where users can /- votes and they can reach negative numbers?
Thanks for the great plugin!
@Shawn - If you want to have a /- vote like digg or reddit then you can use Acts as Voteable. That might be just what you need.
I’m also looking for a way to get a list of things ordered by highest rating.
Here’s the SQL I used, my things that are rateable are called “Writings”
Thanks for a really good tutorial!
Just wondering if there is a method to pull the acts_as_rateable model attributes for a specific user?
My acts_as_rateable model is Businesses, so I can call @business.ratings.each do |b| b.user.login end - this will obviously return all the users that have rated that particular business… I would like to know how to do this in reverse…
So pull a user and get the businesses that they have rated…
So far I have this in the users controller which will only return the business id:
@businesses = Rating.find(:all,
:conditions => [”user_id = ?”, @user.id],
:order => “created_at DESC”)
Does anyone have any ideas?
Thanks
[…] I borrowed heavily from Acts As Rateable by Juixe […]
Anand:
The performance of the average rating calculation can be improved greatly by using SQL instead of ruby.
# Helper method that returns the average rating # def rating Rating.average( :rating, :conditions => { :rateable_id => self.id, :rateable_type => self.class.name }) endSeth:
use the find_ratings_by_user method
with the newer version of rails there will be an error called :
“The :dependent option expects either :destroy, :delete_all, or :nullify (true)”
which appears in:
“vendor/plugins/acts_as_rateable/lib/acts_as_rateable.rb:12:in `acts_as_rateable’”
The Line looks like this :
“has_many :ratings, :as => :rateable, :dependent => true”
just change the true to one of these :
” :destroy This destroys the associated objects”
” :delete_all deletes them directly from the database ”
” :nullify to set the keys to null”
so the line should look somthing like this afterwards :
“has_many :ratings, :as => :rateable, :dependent => :destroy”
Hi, I’m getting the following error when trying to use this plugin with a model in rails 2.0.1:
ArgumentError in MediaController#articles
The :dependent option expects either :destroy, :delete_all, or :nullify (true)
My model is Article, it is currently using the following plugins:
has_self_referential_many_to_many :related
acts_as_taggable
acts_as_commentable
acts_as_rateable
If I comment out the first four plugins and leave rateable in, I still get the error. It’s currently breaking on this line:
Library/Ruby/Gems/1.8/gems/activerecord-2.0.1/lib/active_record/associations.rb:1149:in `configure_dependency_for_has_many’
Can you help?
Ok just thought I’d let you know I fixed the issue by replacing the line 12 in acts_as_rateable.rb to:
has_many :ratings, :as => :rateable, :dependent => :destroy
The :dependent => true option on has_many association was deprecated in 1.1:
http://weblog.rubyonrails.org/2006/4/28/associations-arent-dependent-true-anymore
@Lukas, @Dom - Thanks for the comment. I have update the plugin accordingly.
i have installed successfully acts_as_rateable. excellent plugin! keep your great work!
[…] Acts As Rateable - If you have locations you’ll need to rate them right? Chances are there’s other things on your site that need rating as well, so this cleans up some of the code for this. It’s something that could be done without a plugin, sure, but adding “acts_as_rateable” to a model is all you need to get going. […]
[…] acts_as_rateable ????????????????????? rating […]
[…] Acts As Rateable Plugin Used this Plugin in LWF but followed instructions from Dave Naffis http://www.naffis.com/2006/8/31/rails-ajax-star-rating-system (tags: star.rating plugin acts_as_rateable ajax) […]