CSS Star Rating Systems are all the rage now. Komodo Media brought this idea to the web’s attention with their post CSS Star Rating Redux. This tutorial will show you how to bring this rating system to Ruby on Rails
Example
Several other websites have taken similar approaches:
So how do I get this to work with Rails?
I tried implementing David Naffis’ post “Ruby on Rails, Ajax & CSS Star Rating System”; however, I ran into several issues.
- Limited to one rating per page
- Limted to one type of object
- RJS didn’t seem to work
- Didn’t work with objects that were subclassed
Lets get started!
Note: where ever you see the text “Myobject“, you will want to replace this with the class name of the object that you are rating.
1. Install the acts_as_rateable plugin
piston import http://juixe.com/svn/acts_as_rateable/ vendor/plugins/acts_as_rateable
Note: We use vendor branches for plugins, not script/plugin install so that we can make modifications to the plugin (if needed) and easily update the plugin to the latest revision while keeping the patches that we have created.
2. Create the Migration
script/generate migration add_acts_as_rateable_plugin
file:db\migrate\xxx_add_acts_as_rating_plugin.rb
class ActsAsRateable < ActiveRecord::Migration
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
end
3. Update your existing Model
You will need to include the acts_as_rateable at the top of your class file.
class Myobject < ActiveRecord::Base
acts_as_rateable
…
end
Note: if you are using this with models that are subclassed you will want to put the acts_as_rateable in the parent class only.
4. Create the Ratings Controller
David Naffis’ post Ruby on Rails, Ajax & CSS Star Rating System started me off in the right direction; however, the ratings were not working for classes that were subclassed. Notice the function def get_class_by_name. This function allows the rating controller to find the base class and set the rating at the base class level.
Also note the before_filter :login_required. This verifies that the user is logged in before it runs the rate function. The function login_required is part of the acts_as_authenticated plugin and must be patched in order to work properly with the Ajax request. The patch for acts_as_authenticated is explained in step 8.
script/generate controller ratings rate
file: app\controller\ratings_controller.rb
class RatingsController < ApplicationController
before_filter :get_class_by_name
before_filter :login_required
def rate
return unless logged_in?
rateable = @rateable_class.find(params[:id])
# Delete the old ratings for current user
Rating.delete_all(["rateable_type = ? AND rateable_id = ? AND user_id = ?", @rateable_class.base_class.to_s, params[:id], @current_user.id])
rateable.add_rating Rating.new(:rating => params[:rating], :user_id => @current_user.id)
render :update do |page|
page.replace_html “star-ratings-block-#{rateable.id}”, :partial => “rate”, :locals => { :asset => rateable }
page.visual_effect :highlight, “star-ratings-block-#{rateable.id}”
end
end
protected
# Gets the rateable class based on the params[:rateable_type]
def get_class_by_name
bad_class = false
begin
@rateable_class = Module.const_get(params[:rateable_type])
rescue NameError
# The user is messing with the content_class…
bad_class = true
end
# This means the user is doing something funky…naughty naughty…
if bad_class
redirect_to home_url
return false
end
true
end
end
5. Create the Rate Partial
Again David Naffis’ post Ruby on Rails, Ajax & CSS Star Rating System started my off in the right direction and Igvita’s post Rails 4-State Ajax & CSS Star Rating helped demonstrate out to keep this partial DRY. As usual, I have expanded on both.
file: app\views\rating\_rate.rhtml
< % @convert = %w[one two three four five] %>
{ :url => { :controller => “ratings”, :action => “rate”,:id => asset.id, :rating => x, :rateable_type => asset.class.to_s } },
{ :class => “#{@convert[x-1]}-stars”, :name => “#{pluralize(x,’star’)} out of 5″,
:title => “Rate this a #{x} out of 5″ } ) %>
< % end -%>
Notice: the div is unique ids based on the object’s id (ex: star-ratings-block-1, star-ratings-block-2, …) so that you can include the partial multiple times on a page for multiple objects (currently must be of the same class). This works specifically for the “list” view.
6. Including the Partial
Now that you’ve created the partial, you can simply include it in the view of the object that you will be rating.
< %= render :partial => “rating/rate”, :locals => { :asset => myobject } %>
7. Make it pretty with CSS
At this point you will have a list of numbers that you can click on to set the rating. Using the star_rating.gif image and css from Komodo Media
.star-rating,
.star-rating a:hover,
.star-rating a:active,
.star-rating a:focus,
.star-rating .current-rating{
background: url(‘/images/star_rating.gif’) left -1000px repeat-x;
}
.star-rating{
position: relative;
width: 150px;
height: 30px;
overflow: hidden;
list-style: none;
margin: 0;
padding: 0;
background-position: top left;
}
.star-rating li{
display: inline;
}
.star-rating a,
.star-rating .current-rating{
position: absolute;
top: 0;
left: 0;
text-indent: -1000em;
height: 30px;
line-height: 30px;
outline: none;
overflow: hidden;
border: none;
}
.star-rating a:hover,
.star-rating a:active,
.star-rating a:focus{
background-position: center left;
}
.star-rating a.one-stars{
width: 20%;
z-index: 6;
}
.star-rating a.two-stars{
width: 40%;
z-index: 5;
}
.star-rating a.three-stars{
width: 60%;
z-index: 4;
}
.star-rating a.four-stars{
width: 80%;
z-index: 3;
}
.star-rating a.five-stars{
width: 100%;
z-index: 2;
}
.star-rating .current-rating{
z-index: 1;
background-position: bottom left;
}
.star-ratings-block {
font-size: .75em;
text-align: center;
width: 100%;
}
8. Patch for acts_as_authenticated
As mentioned in Step 4 the acts_as_authenticated plugin must be patched to work with Ajax requests.
If you have already installed the acts_as_authenticated plugin you will need to patch it in 2 locations because the acts_as_authenticated plugin is a code generating plugin.
8A. First we’ll patch the plugin itself
The following code is inserted at line 70 into the access_denied method
file: vendor\plugins\acts_as_authenticated\generators\authenticated\templates\authenticated_system.rb
…
accepts.js do
render(:update) { |page| page.redirect_to(:controller => ‘/account’, :action => ‘login’) }
end
…
I have made a patch available for download: acts_as_authenticated Ajax Patch
8B. Second we’ll patch the lib file that the plugin generated
This is were we add the same patch to the existing lib file that was created by the acts_as_authenticated plugin if you have already installed it into your rails app. This is the exact same code as shown in 8A. In this case I will show you the whole code for the access_denied method.
file: lib\authenticated_system.rb
def access_denied
respond_to do |accepts|
accepts.html do
store_location
redirect_to :controller => ‘/account’, :action => ‘login’
end
accepts.js do
render(:update) { |page| page.redirect_to(:controller => ‘/account’, :action => ‘login’) }
end
accepts.xml do
headers["Status"] = “Unauthorized”
headers["WWW-Authenticate"] = %(Basic realm=”Web Password”)
render :text => “Could’t authenticate you”, :status => ’401 Unauthorized’
end
end
false
end
9. Test Cases
Finally it wouldn’t be a rails app if you didn’t include the test. Below you’ll find two test to confirm that the rating system works and that the user must be logged in to rate an object.
# Test campaign rate
def test_campaign_rate
@request.env['HTTP_REFERER'] = ‘/myobject/list’
login_as(:jdoe)
post :rate, {:id => 1, :rateable_type => “Myobject”, :rating => 5 }
assert_equal 5, Myobject.find(1).rating
end
# Test campaign rate – make sure you must be logged in
def test_campaign_rate_unsuccessful_if_not_logged_in
@request.env['HTTP_REFERER'] = ‘/myobject/list’
post :rate, {:id => 1, :rateable_type => “Myobject”, :rating => 5 }
assert_equal 0, Myobject.find(1).rating
end
Out in the wild
Here’s where you can go check it out on the website Obsidian Portal http://www.obsidianportal.com/campaigns/list.
Note: As mentioned above the rating table uses a user_id to make sure that there is only one rating per user per object.
References
http://komodomedia.com/blog/index.php/2006/01/09/css-star-rating-part-deux/
http://komodomedia.com/blog/index.php/2007/01/20/css-star-rating-redux/
http://www.igvita.com/blog/2006/09/02/4-state-rails-ajax-css-rating/
Alternatives Ideas
Update 2007-11-30: All code corrections from the comments have been integrated into this article..

May 7th, 2007 at 7:46 pm
Thanks so much for this amazing and very clear tutorial !!
I have tried to night the implementation on a small site I’m currently developing. All worked fine except at one point.
For example, if I rate an object with 2, I can’t see after the two stars taking
the orange color.
What do you think it is ?
Sorry if it’s a stupid question … I’m new to rails and css and I really appreciate your help guys
J.
May 8th, 2007 at 7:25 am
Jonas,
It appears to be to be an issue with the CSS source highlighting that I use: http://erik.range-it.de/wordpress/plugins/syntaxhighlighter/. It is replacing an the word bottom with bottombottom in the background-position element.
I strongly recommend clicking on the “View Plain” link at the top of the source box to when you copy the source code so that you are coping exactly what I have typed.
Hope this helps. When you get it up and running feel free to drop a link with the website that is implementing this post.
May 17th, 2007 at 10:46 am
[...] you’ve got the Ajax CSS Star Rating System with acts_as_rateable (A MUST READ). Now you want to list the top rated objects and how many votes they’ve [...]
May 29th, 2007 at 7:48 am
Just a heads up to anyone who is trying to implement this, the actual acts_as_rateable plugin to use is
script/plugin install http://juixe.com/svn/acts_as_rateable
the blog post is using: svn://rubyforge.org/var/svn/rateableplugin/trunk
which I think is wrong…
May 30th, 2007 at 10:29 am
Alfred,
Nice catch. They both are called acts_as_rateable. The correct one is from http://www.juixe.com/. I have update the post. Thanks for the feedback.
June 7th, 2007 at 8:39 pm
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 tutorial!
June 7th, 2007 at 9:01 pm
Never mind, I figured it out. If anyone else is interested in doing so, you can simply add a method called “total_rating” or something of the similar and define it as so:
def total_rating
total = 0
ratings.each { |r|
total = total + r.rating
}
total
end
June 17th, 2007 at 5:24 am
To any noobs giving this a shot, there are a couple of small typos here. In section 4
script/generate controller ratings rate
Should be
script/generate controller rating rate
Also
render :update do |page|
page.replace_html “ratings-block-#{rateable.id}”, :partial => “rate”, :locals => { :asset => rateable }
page.visual_effect :highlight, “ratings-block-#{rateable.id}”
end
Should be
render :update do |page|
page.replace_html “star-ratings-block-#{rateable.id}”, :partial => “rate”, :locals => { :asset => rateable }
page.visual_effect :highlight, “star-ratings-block-#{rateable.id}”
end
Outside of those 2 small issues, great write-up!
June 19th, 2007 at 5:06 am
@Dave,
Thanks for the typo catches. Ryan (the author) is out of town, but I’ll make sure he gets your comments. If he can confirm the typos we’ll fix them.
Thanks again.
July 2nd, 2007 at 12:38 pm
I found another small error. In the css find .one-star and change it to .one-stars this will let let you rate something 1 star instead of the first star being two stars.
July 2nd, 2007 at 12:39 pm
^edit^
This is only if you use the downloaded css from komodo media.
July 2nd, 2007 at 1:12 pm
[...] read the comments as well to pick up a couple of tips and get some typos in the main post corrected.read more | digg [...]
July 13th, 2007 at 6:33 am
Help!
Noob trying to get this working in a project.
Second go around and I must say I appreciate everyones work getting this as clear (and correct) as possible.
In _rate.rhtml should all “asset” references be changed to “myobject” basically?
Thanks!!!
Andrew
July 13th, 2007 at 10:18 am
Sorry for that last post. I figured out my last question with a bit more perseverance and seem to be making progress. Sorry about the poor question. The answer to my question was “no”.
I am still having trouble though. The data does not seem to be actually hooked to the backend though its displaying pretty dynamic stars in my view. Clicking on them just does not change anything. I am worried I need to do some include statements to use the javascript. I am using the latest version of InstantRails as my base.
What else can I check for???
As before. Any and all help is GREATLY appreciated.
Andrew
July 16th, 2007 at 9:08 am
Anyway to do partial stars?
instead of half or full..to show 4.3 of a star, possibly without making a billion different renders of the images?
July 18th, 2007 at 1:24 pm
Andrew,
Make sure you have enabled javascript. The best way to check is to see the source of the web-page. You should see javascript tags there. If you don’t have it, put this in your application.rhtml layout:
I am still not able to save the rankings into the database, but I can see in the log file that the view is collecting the right data. Post back your progress, if you can.
Kaushik
July 18th, 2007 at 1:25 pm
Andrew,
The form ate my javascript include command, but you should be able to google for it. It is a simple one-liner.
Kasuhik
August 6th, 2007 at 3:29 pm
[...] Midnight Oil » Blog Archive » Ajax CSS Star Rating with acts_as_rateable (tags: rails ratings tutorial ajax cakephp) [...]
August 16th, 2007 at 4:49 pm
Alright, noob question… what goes in the myobject spot where the partial is being rendered? Everything I try is undefined or wrong number of args.
August 24th, 2007 at 11:11 pm
Thanks everyone for the great feedback. Sorry for the delay in updates to this post. I have returned from my travels and will be updating this post shortly. Also, I will have a new revamped of this version of this post in the coming weeks.
September 5th, 2007 at 7:59 am
Hey there – really cool tute!
Just wondering if in the revamped version you could add a ‘non-ajaxed’ version? Thanks
September 5th, 2007 at 10:05 am
Seth,
Thanks for the comment.
With the revamp I plan on continuing with the Ajax version; however, I do plan to make it more non-Ajax friendly by adding a redirect_back_or_default if not Ajax.
In the meantime, I think if you change the link_to_remote with a form_tag. Then add the following to the bottom of the rate function within RatingsController. (This is NOT tested).
redirect_back_or_default(home_url)
If you want to use it with the Ajax version, try something like this:
respond_to do |format|
format.html { redirect_back_or_default(home_url) }
end
September 5th, 2007 at 10:20 pm
Hey all, I’m glad someone asked about a non-ajaxed version, just what I was after!
Thanks for the awesome tute – a real great walkthough on how to set it all up!
Just curious though, I call quite a few times on a page (in the list action) and it’s making an SQL query ( SELECT count(*) AS count_all FROM ratings WHERE (ratings.rateable_id = 1 AND ratings.rateable_type = ‘Business’) ) for every (in my case) Business.
I have just finished off a tute from Ryan Bates about counter_cache-ing and I tried implementing that into the business model BUT it didn’t work because of the polymorphic relationship…
Just curious if anyone has implemented a counter_cache-ing approach?
Thanks.
September 6th, 2007 at 5:13 pm
Hello again, just another question
.
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:
rder => “created_at DESC”)
@businesses = Rating.find(:all,
:conditions => [”user_id = ?”, @user.id],
Does anyone have any ideas?
Thanks
September 6th, 2007 at 6:43 pm
Phillip,
acts_as_rateable has 2 methods built in that you should check out:
find_ratings_by_user
rated_by_user?
I suggest opening up your console (ruby script\console) and try the following:
@user = User.find_by_id(1)
@businesses = Business.find_ratings_by_user(@u)
@businesses.each { |r| print “#{r.rating} | #{r.rateable_id}” }
And…
@user = User.find_by_id(1)
@business = Business.find_by_id(1)
@rated_by_user = @business.rated_by_user?(@user)
I am working on a patch to acts_as_rateable to return the top rated objects with the number supplied by the user. So you can say Business.find_top_rated(10) to get the top 10 best rated Businesses. I haven’t completed it yet.
Ryan
September 6th, 2007 at 10:16 pm
Ryan,
I have tried using find_ratings_by_user and it only gives back the rateable_id, I want to get back the properties of that id. In my case it’s the business model (it has a name column).
@user = User.find_by_id(1)
@businesses = Business.find_ratings_by_user(@u)
@businesses.each { |r| print “#{r.rating} | #{r.rateable_id}” }
I’d also like to be able to call: r.business.name, r.business.created_at et cetera.
Thanks for replying so quick, you’ve been the greatest help!
September 6th, 2007 at 11:24 pm
Okies – I still couldn’t figure it out so I wrote some SQL that seems to make it work pretty good. In the acts_as_rateable.rb file in the lib I added:
# Helper class method to lookup model attributes associated with acts_as_rateable
def find_businesses_ratings_by_user(user)
@businesses = find_by_sql(“SELECT * FROM Businesses INNER JOIN Ratings ON Businesses.id = Ratings.rateable_id WHERE Ratings.user_id = #{user.id}”)
end
This lets me do:
And I get all the info I need
– if anyone knows a better way to do this I would be interested in knowing.
Thanks
September 11th, 2007 at 6:36 am
Hmm problem 1 – the form ate my junk, it looked like
@businesses.each do |r|
r.name, r.email (all taken from the business model
Problem 2 – this SQL is returning the ratings tables id as the businesses id…
Any ideas? Thanks
September 22nd, 2007 at 3:11 am
Awesome tutorial! I changed the images to BE NOT SO BIG
but otherwise used pretty much as is (with typo corrections).
Thanks!
October 1st, 2007 at 6:12 am
hi this is an awesome tutorial!
really helped me along
now i have just one question left:
as i am using restful routings i keep getting this routing error when i call link_to_remote:
ActionController::RoutingError (no route found to match “/ratings_controller/rat
e/33″ with {:method=>:post}):
doew anyone have an idea how to solve this?
thx
October 3rd, 2007 at 1:00 pm
I am having the same routing issue as Sam. When I figure it out I will post.
October 3rd, 2007 at 1:01 pm
Doh
You need to add this to your routes.
map.resources :rating, :member => { :rate => :put }
or just add map.resources :rating and then change the def rate to def new so it is restful.
October 3rd, 2007 at 1:06 pm
sorry, change the :put to :post.
October 18th, 2007 at 7:08 am
I keep getting a RJS error in all my browsers (Firefox, IE 6 & 7). The error says: TypeError ($element) has no properties. Then another popup comes up with the contents of the html replacement code that is trying to run. I’ve pin pointed the code that is causing it and it is this part in the controller:
render :update do |page|
page.replace_html “star-ratings-block-#{rateable.id}”, :partial => “rate”, :locals => { :asset => rateable }
page.visual_effect :highlight, “star-ratings-block-#{rateable.id}”
end
If I remove that code, the error goes away, but I also do not get the immediate refresh to the page. Has anyone else seen this? It only happens when running the server in development mode, in production mode the error does not occur.
The piece on the html page that I am trying to refresh, is inside a table, so I thought that might be a problem. But, after moving the code outside the table, I still see the errors.
Any ideas? Thanks!!
October 19th, 2007 at 8:52 am
thanx james, it worked just fine
December 20th, 2007 at 1:12 am
[...] For that, I started with the Midnight Oil tutorial [...]
January 16th, 2008 at 12:36 pm
I am implementing this plugin on a site but need to be able to rate multiple things prior to saving. For example, if I wanted to rate the food(4 stars), service(5 stars) and atmosphere(4 stars). How should I approach this using the tutorial provided.
Thanks in advance
January 16th, 2008 at 10:25 pm
Marion,
Basically as mentioned in the post is that you just create a model, add that acts_as_rateable to the object. Then in the controller when you’re creating a new rating just make sure to specify the class_name and the id, which map to the rateable_type and rateable_type_id.
Note, this post requires each item to be an model. If you make food, service, or atmosphere attributes of the Resturant model, this method will NOT work and you’ll have to come up with something clever.
If food, service, or atmosphere are all separate models that belong_to a restaurant you can do this:
class Restaurant < ActiveRecord::Base
acts_as_rateable
has_one :service
...
end
class Service < ActiveRecord::Base
acts_as_rateable
belongs_to : Restaurant
...
end
@restaurant = Restaurant.find(:first)
< %= render :partial => “rating/rate”, :locals => { :asset => @restaurant } %>
< %= render :partial => “rating/rate”, :locals => { :asset => @restaurant.service } %>
Everything else is automatic, hope it helps…
January 17th, 2008 at 9:56 pm
Thank you for the response, it certainly got me much closer. Now I am getting stuck with making the updates to the controller and am getting an error. I am not quite sure what you mean when you say update class and id. Please understand that I am relatively new to ruby. Here’s what I have in a nutshell
I am first trying to display a page with Host information that will allow users to rate multiple things.
HostController
def show
@host = Host.find(params[:id])
@hostRating = Host.find(:first)
end
I created a class called Support that belongs to a Host.
class Support < ActiveRecord::Base
acts_as_rateable
belongs_to :Host
@supportRating = Host.find(:first)
end
My partial sets the asset collection
“rate”, :locals => { :asset => @supportRating.support } %>
Now I have made no update to the ratings controller because I am a little confused. It looks like the _rate partial references the class that is passed via the collection. Does it look something like this: rateable = @host.support.find(params[:id])
Any direction here would be great. I am trying to make sense of this and feel like I am getting close to truly understanding the logic.
Btw…everything else is the same as what you have in your tutorial (ie. rate partial)
Thanks again for your time and help!
Marion
February 17th, 2008 at 4:20 pm
Hello!
For some reason, when I click on a rating when I’m not logged in, it redirects me to the login page (as it should), however, when I am logged in and I click on a rating, it doesn’t work – it doesn’t rate the content.
Please help!
David Pham
February 18th, 2008 at 6:18 am
David,
That’s an existing issue that I know about.. I haven’t found a great way to solve it yet though. If you use the acts_as_authenticated store_location it only stores the javascript.. I’ll let you know if I get it figured out.
Ryan
February 23rd, 2008 at 7:38 pm
Great post!
February 27th, 2008 at 7:18 pm
Love the plugin! I would like to add an additional field to the table, called thing_id. I’ve tried passing another local variable called :thing_id => @thing.id, but when I render the partial in the view, I get this error from the controller:
NameError (undefined local variable or method `thing_id’ for #):
This is how i changed the render partial call in my view:
“ratings/rate”, :locals => { :asset => current_user, :thing_id => @thing.id } %>
why wouldn’t the local variable “thing_id” be available to me to use in the Ratings Controller in the Rate action?
Thanks for any insight!!
February 27th, 2008 at 7:19 pm
whoops … the error got cut off … here is the full text:
NameError (undefined local variable or method `thing_id’ for #):
March 5th, 2008 at 10:41 am
Okay. Say you wanted to have multiple models to be rated in one view. Well you’ll find that it still rates correctly upon a page refresh, but the javascript only effects the first partial. This is easily rectified. You just have to change two pieces of code and your done.
The first you’ll have to change is in your ratings/rate partial:
change this…
<div id=”star-ratings-block-” class=”star-ratings-block”>
to this…
<div id=”star-ratings-block-” class=”star-ratings-block”>
And then change you rating controller:
change this….
render :update do |page|
page.replace_html “star-ratings-block-#{rateable.id}”, :partial => “rate”, :locals => { :asset => rateable }
page.visual_effect :highlight, “star-ratings-block-#{rateable.id}”
end
to this…
render :update do |page|
page.replace_html “star-ratings-block-#{@rateable_class}”, :partial => “rate”, :locals => { :asset => rateable }
page.visual_effect :highlight, “star-ratings-block-#{@rateable_class}”
end
March 5th, 2008 at 10:43 am
WordPress ate my code in the portion of my comment. What you want to change is asset.id to asset.class. We do this so that the javascript finds the partial to update by it’s name rather than the id.
April 28th, 2008 at 9:12 am
The current rating portion of the rating/rate partial assumes that your star container will always be 150px in length.
If you use relative units here, designers can resize the star rater without touching your Rails app code.
http://pastie.caboo.se/188152
May 20th, 2008 at 5:59 am
Hi,
I have used this plugin in my application.functionality is working.
But stars colours didn’t change with mouse over.and Current rating is not displaying above the stars..
please give me solution for this.
thanks,
ravi.
June 24th, 2008 at 7:22 pm
I’ve been using this plugin for months now. whenever a user rates something, the browser shrinks the text to 150% smaller, after save???
anyone else have that happen?
So if i rate a product a 4 star, the ajax call will happen, the browser will refresh that one part and bammo… the text is written in 3 pt font. i refresh the page, and the call is made, and all that jazz, just it’s a css issue. obviously it’s something i did… but wanted to report, for others.
Also, i can’t get those methods to work. I just want to print what my user rated, beside a review of the product. having trouble with the existing methods, and with find_all_by_user_id_and_rateable_type_and_rateable_id(params[:whatever]) isn’t working all that well.
thoughts?
July 11th, 2008 at 1:41 am
nerb.. change the font size in star-ratings-block to 1em.. should work fine..
July 11th, 2008 at 1:47 am
great tutorial ryan.. ure being a lot of help to us starters..
one problem though.. tried using acts_as_authenticated with this.. there’s however no response whatsoever when i try to rate.. no refresh,error,redirect.. nothing.. I HAVENT logged in.. so its not the problem David pointed out.. if i remove the filter then things work fine.. i then rolled back acts_as_authenticated and tried my own authentication that i used on another app.. even that aint working.. any help?
also.. how can i debug in a way as to be able to see all the calls to methods and actions being made..
July 24th, 2008 at 6:02 pm
after 7 months of using this tutorial, it now craps out on me. firebug reports this error. Anyone else? i have no were to turn… $H(object).toQueryString is not a function
toQueryString(Object)all.js (line 144)
request(“/rating/57/rate?rateable_type=Post&rating=4″)all.js (line 1201)
initialize(function(), “/rating/57/rate?rateable_type=Post&rating=4″, Object asynchronous=true evalScripts=true)all.js (line 1185)
wrap()all.js (line 238)
klass()all.js (line 48)
onclick(click clientX=0, clientY=0)57-makeup-review-… (line 1)
[Break on this error] return $H(object).toQueryString();
August 21st, 2008 at 1:51 am
Hey, this seems like a great tutorial but I can’t get it to work. I’m using rails 2.1 (Instant Rails on Windows XP)…
I’m getting this error when I try adding the acts_as_rateable to my model
NameError in ProductsController#show
-undefined local variable or method `acts_as_rateable’
August 21st, 2008 at 9:35 am
Ryan,
We haven’t actually upgraded to Rails 2.1 yet, so I’m not sure if it is compatible. We’ve actually moved to acts_as_rated because of it’s use of additional columns for caching.
I’m working on an updated tutorial (and possibly a plugin), but it’s going to take a little while since I’m in the process of moving.
Note, the reason we haven’t upgraded from 2.0.2 to 2.1 is because when we tried we had a ton of incorrect IP Spoofing errors occur simply because people were using a proxy.
Ryan
August 25th, 2008 at 3:05 am
Seems kind of heavy , wil make my own functions SOrry … didnt like the plugin sends to many calls.
September 11th, 2008 at 8:05 am
Will this work with restful authentication?
September 15th, 2008 at 11:59 am
@tyanlion -
It definately should. We used acts_as_authenticated for this project, but it’s extremely similar to RESTful Authentication. Let us know how you fair.
September 17th, 2008 at 7:22 pm
Hi Ryan!
We used it with restful_authentication, however, it did not work.
It takes the user to login, then to their destination default page after login.
Without the patches, it takes the user to the login page and then spits out JS to the browser (the .rjs), which is displayed as text (bleh). http://www.amahi.org/apps for an example.
Also, anyone have any ideas on how to make the star block appear nicely when we have an image with text around and it does not fall all the say to the left, such as in this example?
http://www.amahi.org/apps/valencia-theme
Thanks in advance!
September 17th, 2008 at 8:51 pm
OK, so for restful_authentication we had to store_location in the plugin and the generated code from the plugin, and also in the rate method, respond for js and html separately – html takes the redirection.
We still have the CSS artifact – anyone?
Amahi
September 17th, 2008 at 10:23 pm
We believe we have solved the CSS artifacts – we had badly copied stylesheets.
October 3rd, 2008 at 7:09 pm
piston import is not working it results in this:
resulted in an error: (RuntimeError)
October 3rd, 2008 at 7:13 pm
will using svn checkout http://juixe.com/svn/acts_as_rateable/ vendor/plugins/acts_as_rateable
work instead of piston import?
October 4th, 2008 at 6:32 am
@tyanlion -
If you’re using subversion; great! Make sure you’re using the version of Piston on RubyForge: http://rubyforge.org/projects/piston. If you’re having problems with v1.4.0 you could try version 1.0.0. The version of Piston on GitHub is still a “work in progress” and I haven’t had any luck with it. If you’re using git just use script/plugin install http://juixe.com/svn/acts_as_rateable/ for now.
Piston rocks because you can set the external flag, but it doesn’t automatically pull the newest plugin code when you do an svn up; only when you do an piston update. You could do a script/plugin install -x http://juixe.com/svn/acts_as_rateable/, but as mentioned every time you do an SVN up or deploy you will git the bleeding edge version of the plugin (which is HIGHLY not recommended).
Hope that helps.
October 7th, 2008 at 4:11 am
Ryan thx for your help. I have managed to get the star system working. however there is still one problem. even after i have rated the object, i am able to re-rate it again and again. how do i stop the re-rating from taking place?
October 7th, 2008 at 7:03 am
@tyanlion -
You will need to check to see if you’re user has rated the item already. If so, render a partial that doesn’t have the links.
October 8th, 2008 at 1:13 am
Ryan there seems to be a problem in the star system. when i rate a star an extra appears in the code.
example:
3.5/5 Stars (2 votes)
————————————
after rating becomes:
3.5/5 Stars (2 votes)
——————————–
Because there are 2 of these divs when the stars are rated the end result is stars which are smaller in size than the original.
When i re-rate it however the stars are the same size. which means no div has been added, however there still those 2 divs.
Is there a way to get rid of the extra div??
October 8th, 2008 at 1:15 am
Sorry have to repost apparently div does not show
Ryan there seems to be a problem in the star system. when i rate a star an extra {div id=”star-ratings-block-7″ class=”star-ratings-block”} appears in the code.
example:
{div id = “star-ratings-block-7″ class=”star-ratings-block”}
3.5/5 Stars (2 votes){br /}
{ul class=’star-rating’}
————————————
after rating becomes:
{div id = “star-ratings-block-7″ class=”star-ratings-block”}
{div id = “star-ratings-block-7″ class=”star-ratings-block”}
3.5/5 Stars (2 votes){br /}
{ul class=’star-rating’}
——————————–
Because there are 2 of these divs when the stars are rated the end result is stars which are smaller in size than the original.
When i re-rate it however the stars are the same size. which means no div has been added, however there still those 2 divs.
Is there a way to get rid of the extra div??
October 8th, 2008 at 4:21 pm
nevermind i managed to solve it myself. you just need another partial that does not have the div inside of it. and you have to tell the controller to page replace that
October 8th, 2008 at 7:35 pm
@tyanlion -
Glad you figured it out. The numbered blocks were simply so that you can update multiple ratings on one page. You wouldn’t need them if you’re just rating one item.
October 21st, 2008 at 6:45 pm
As an fyi, I’ve just noticed that the acts_as_rateable plugin now incorporates alot of the methods you created. now you just have to pass @product.rate_it(score, user_id) and it calculates the totals and only allows the user to input it once too.
I’m trying to refactor your tutorial with the new methods. Your tutorial has been a god send for about a year, but now it’s time to update based on the new methods.
November 11th, 2008 at 10:28 pm
To get this to work out with Rails 2.1.2 I had to:
rather than use the old migration, you can just issue script/generate acts_as_rateable_migration and then migrate
RatingController: rateable.rate_it params[:rating], params[:session_id]
I’m using session for the user_id as I need anonymous rating..it’s not going to be perfect but it seems to do alright.
Routes, at this time i just need the rate action
map.rate ‘/rate’, :controller => ‘rating’, :action => ‘rate’
I had to change the link_to_remote in the partial view to
{
:controller => “rating”, :action => “rate”,
:id => asset.id, :rating => x, :rateable_type => asset.class.to_s
},
:html => { :class => “#{@convert[x-1]}-stars”, :name => “#{pluralize(x,’star’)} out of 5″,
:title => “Rate this a #{x} out of 5″ } ) %>
Without this tutorial, as this is my first ever Rails app, I would’ve been looking around for quite some time.
Thanks
November 19th, 2008 at 9:22 am
@Richard -
Thanks for the info!
December 9th, 2008 at 7:22 am
Hey Ryan.
First of all, great tutorial!!! Im still a Rails newbie and working on my first app using google maps.
But I feel it is “out of date”. You think there will be an updated version comming?
Thanks
December 9th, 2008 at 8:11 am
@Antonios -
Antonios,
Thanks for the comment. Yeah, it is quite out of date and not code in the RailsWay. I’m intending to make it into a plugin, but it’s taking a while
Ryan
December 29th, 2008 at 10:06 am
Hey Ryan, good tutorial and info. Wanted to send praise and encouragement for rolling this work into a plugin — I know it would be very popular. Cheers, R
January 6th, 2009 at 11:04 am
Ryan,
Great tutorial – I had read the others, but I really like what you were able to do to make things a little more dynamic. I’m pretty sure I have a good understanding of how this is all supposed to work.
I’ve got it implemented on our dev site (www.profoundponderings.com:3000) and the problem I am having is that it works fine on IE under Windows, but doesn’t display the images on any other browser (FF, Opera on Windows, Safari, FF on Mac). The mystifying part to me though is that I am looking right at your example here on this page and I can definitely see the images and can operate the rating etc.
I went and compared your CSS with the one you display in the article and have found them to be pretty much identical (some meaningless parameters reordered). Maybe I missing something obvious, but I thought you might be able to tell quickly from a peek at it (I know this is asking a lot, but I am pretty stumped after a number of hours). The only difference is that I added a border around the UL just to be sure it was on the page somewhere.
January 6th, 2009 at 5:21 pm
Grr… sorry I meant port 3001 not port 3000
January 6th, 2009 at 6:44 pm
No need to take a look at it… I figured out what the CSS issue was. It appears that the “background” shorthand in star_rating is ignored in most other browsers other than IE. I had to explicitly repeat the background-image instruction for each of the other properties (hover, current_rating) in order for it to work with the rest of the planet. Pretty weird, but very, very happy with the results now. Of course what was really odd as well was that this page works correctly as is.
August 12th, 2009 at 9:36 am
I’m not sure if it’s just me, but some of the code for the partial seems to be missing in the tutorial.
November 30th, 2009 at 11:27 pm
How, did you achieve the “special effect” with your tags [right under your search form] ?
Thanks.
August 27th, 2010 at 7:00 am
Below is a link about VPN . Talking to the IT guy is a good thing even if you are not well versed. Being honest leads to trust and respect. As a tech for more than 30 years I have more respect for a person that wants to understand then one who tries to fake it. Believe me I have a few key questions that tips me off to a faker. There are many ways to connect to the work system from home. Ask the IT for recommendations, reason for those recommendations and the plusses and minuses for each. The IT person should be willing to present this as a formal proposal on paper for your study.