<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Wolfmans Howlings: Developing a social networking site part 2 - rating stars</title>
    <link>http://blog.wolfman.com/articles/2007/06/23/developing-a-social-networking-site-part-2-rating-stars</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>A programmers Blog about Ruby, Rails and a few other issues</description>
    <item>
      <title>Developing a social networking site part 2 - rating stars</title>
      <description>&lt;p&gt;In 
&lt;a href="http://blog.wolfman.com/articles/2007/05/31/snow-dogs-r-us-a-rails-based-social-networking-site"&gt;part 1&lt;/a&gt;
I outlined my project to implement &lt;a href="http://snowdogsr.us"&gt;snowdogsr.us&lt;/a&gt;
a social networking site for snow dogs.&lt;/p&gt;

&lt;p&gt;I am pleased to announce that version 1 of this site is up, however I
had to make some trade-offs to get it up this far. I needed to
prioritize my goals and just get the essentials implemented.&lt;/p&gt;

&lt;p&gt;So the ability to create Posts, Events and Places, and add photos of
your dogs was goal number 1. The linking to friends was postponed,
although most of the logic was implemented, I couldn't figure out how
to expose that in an intuitive UI.&lt;/p&gt;

&lt;p&gt;The first thing I wanted was to be able to rate the various Posts
and Places people entered, and how better to do that than to copy the
Netflix and Google groups method of showing 5 stars and clicking on
them to rate the item.&lt;/p&gt;

&lt;p&gt;To that end some googling found an 
&lt;a href="http://komodomedia.com/blog/index.php/2007/01/20/css-star-rating-redux"&gt;excellent CSS method&lt;/a&gt;
to do this,
all I had to do was integrate it into Rails. I had some extra business
rules I needed to deal with&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only people logged in can rate an article&lt;/li&gt;
&lt;li&gt;The creator of the article can not rate their own article&lt;/li&gt;
&lt;li&gt;If the rating is readonly then it still needs to be displayed as
stars, just not clickable ones.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Out of the box the Stars were always clickable, so I needed a way to
show readonly stars when the user was not allowed to rate the article,
luckily the above referenced blog explained how to do that in the
blogs comments.&lt;/p&gt;

&lt;p&gt;I'm using the acts_as_rated plugin, which works fine so long as you
don't try using the optimized method of creating a stats table, that
method didn't seem to work, and for now I'll just let the SQL do the
math.&lt;/p&gt;

&lt;p&gt;As I have many models that acts_as_rated I needed to write a helper to
display the stars, and handle the rating clicks, and the business
logic.&lt;/p&gt;

&lt;p&gt;The helpers look a little ugly as you need to figure out what the
parent model is.&lt;/p&gt;

&lt;p&gt;So here is the code that goes in application_helper.rb&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;star_rating&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;rating&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;obj_type&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;allow_rate&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;per&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;rating&lt;/span&gt; &lt;span class="punct"&gt;&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt; &lt;span class="punct"&gt;?&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;rating&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="number"&gt;5.0&lt;/span&gt;&lt;span class="punct"&gt;)*&lt;/span&gt;&lt;span class="number"&gt;100&lt;/span&gt; &lt;span class="punct"&gt;:&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;;&lt;/span&gt;
    &lt;span class="ident"&gt;url_meth&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;rate_&lt;span class="expr"&gt;#{obj_type}&lt;/span&gt;_path&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;.&lt;/span&gt;&lt;span class="ident"&gt;to_sym&lt;/span&gt;
    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;allow_rate&lt;/span&gt;
      &lt;span class="ident"&gt;links&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;
        &lt;span class="ident"&gt;link_to&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="ident"&gt;send&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;url_meth&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt;&lt;span class="symbol"&gt;:id&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:rate&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;}),&lt;/span&gt; &lt;span class="symbol"&gt;:method&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:put&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:class&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;one-star&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:title&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;1 star out of 5&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;),&lt;/span&gt;
        &lt;span class="ident"&gt;link_to&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="ident"&gt;send&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;url_meth&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt;&lt;span class="symbol"&gt;:id&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:rate&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;}),&lt;/span&gt; &lt;span class="symbol"&gt;:method&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:put&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:class&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;two-stars&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:title&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;2 stars out of 5&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;),&lt;/span&gt;
        &lt;span class="ident"&gt;link_to&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;3&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="ident"&gt;send&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;url_meth&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt;&lt;span class="symbol"&gt;:id&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:rate&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;3&lt;/span&gt;&lt;span class="punct"&gt;}),&lt;/span&gt; &lt;span class="symbol"&gt;:method&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:put&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:class&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;three-stars&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:title&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;3 stars out of 5&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;),&lt;/span&gt;
        &lt;span class="ident"&gt;link_to&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;4&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="ident"&gt;send&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;url_meth&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt;&lt;span class="symbol"&gt;:id&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:rate&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;4&lt;/span&gt;&lt;span class="punct"&gt;}),&lt;/span&gt; &lt;span class="symbol"&gt;:method&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:put&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:class&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;four-stars&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:title&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;4 stars out of 5&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;),&lt;/span&gt;
        &lt;span class="ident"&gt;link_to&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;5&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="ident"&gt;send&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;url_meth&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt;&lt;span class="symbol"&gt;:id&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:rate&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;5&lt;/span&gt;&lt;span class="punct"&gt;}),&lt;/span&gt; &lt;span class="symbol"&gt;:method&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:put&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:class&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;five-stars&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:title&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;5 stars out of 5&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)]&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="ident"&gt;r&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt; &lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="ident"&gt;r&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;lt;span class=&lt;span class="escape"&gt;\&amp;quot;&lt;/span&gt;inline-rating&lt;span class="escape"&gt;\&amp;quot;&lt;/span&gt;&amp;gt;  &amp;lt;ul class=&lt;span class="escape"&gt;\&amp;quot;&lt;/span&gt;star-rating&lt;span class="escape"&gt;\&amp;quot;&lt;/span&gt;&amp;gt; &amp;lt;li class=&lt;span class="escape"&gt;\&amp;quot;&lt;/span&gt;current-rating&lt;span class="escape"&gt;\&amp;quot;&lt;/span&gt; style=&lt;span class="escape"&gt;\&amp;quot;&lt;/span&gt;width:&lt;span class="expr"&gt;#{per}&lt;/span&gt;%;&lt;span class="escape"&gt;\&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;

    &lt;span class="comment"&gt;# if we can't rate then just show stars&lt;/span&gt;
    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;allow_rate&lt;/span&gt;
      &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;..&lt;/span&gt;&lt;span class="number"&gt;4&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
        &lt;span class="ident"&gt;r&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;lt;li&amp;gt;&lt;span class="expr"&gt;#{links[i]}&lt;/span&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
      &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="ident"&gt;r&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;lt;/ul&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="ident"&gt;r&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;&amp;lt;span class=&amp;quot;prompt&amp;quot;&amp;gt;Click star to rate&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;allow_rate&lt;/span&gt;
    &lt;span class="ident"&gt;r&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;render_rating&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;o&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;allow_rating&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="constant"&gt;true&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;  
    &lt;span class="ident"&gt;can_rate&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;allow_rating&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="ident"&gt;logged_in?&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="punct"&gt;!&lt;/span&gt; &lt;span class="ident"&gt;o&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;created_by?&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;current_user&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;o_type&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;o&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;class&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;downcase&lt;/span&gt;

    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;o&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;rated?&lt;/span&gt;
      &lt;span class="ident"&gt;r&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Rating &lt;span class="expr"&gt;#{o.rating_average}&lt;/span&gt;/5 by &lt;span class="expr"&gt;#{pluralize(o.rated_count, 'person')}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
      &lt;span class="ident"&gt;r&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="ident"&gt;star_rating&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;o&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;rating_average&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;o_type&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;o&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;can_rate&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="keyword"&gt;elsif&lt;/span&gt; &lt;span class="ident"&gt;can_rate&lt;/span&gt;
      &lt;span class="ident"&gt;r&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Not yet Rated&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
      &lt;span class="ident"&gt;r&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="ident"&gt;star_rating&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;o_type&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;o&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;can_rate&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="keyword"&gt;else&lt;/span&gt;
      &lt;span class="ident"&gt;r&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="ident"&gt;r&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The render_rating method is what you call from your view, the
star_rating method generates the HTML.&lt;/p&gt;

&lt;p&gt;(I presume you included the star_rating.css which is available from
the above mentioned blog, and the acts_as_rated plugin.)&lt;/p&gt;

&lt;p&gt;The render_rating method takes the model object being rated, and an
optional override to allow_rating or not (which determines if the
stars are clickable or not).&lt;/p&gt;

&lt;p&gt;I include some text saying what the rating is and how many people have
rated the article, followed by the stars showing the rating.&lt;/p&gt;

&lt;p&gt;I have all my ratings set to 1 to 5, YMMV.&lt;/p&gt;

&lt;p&gt;In my view (HAML) code I have...&lt;/p&gt;

&lt;p&gt;= render_rating(place)&lt;/p&gt;

&lt;p&gt;Which will render the rating for the current place article.&lt;/p&gt;

&lt;p&gt;the Place model has this code...&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;acts_as_rated(:rating_range =&amp;gt; 1..5, :rater_class =&amp;gt; 'Person')
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;because I have a Person class as the rater rather than the default
User.&lt;/p&gt;

&lt;p&gt;The rating percentage is calculated using..&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  per= rating &amp;gt; 0 ? (rating/5.0)*100 : 0;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which is used by the CSS to highlight the stars correctly.&lt;/p&gt;

&lt;p&gt;I use RESTful routing so the links are generated using named
routes, however as the named route will be different depending on the
Model object being rated I need to use this code...&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="comment"&gt;# added to routes.rb to provide a rate method&lt;/span&gt;
&lt;span class="ident"&gt;map&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;resources&lt;/span&gt; &lt;span class="symbol"&gt;:places&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:member&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="symbol"&gt;:rate&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:put&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;

&lt;span class="comment"&gt;# added to places_controller.rb to handle the new route&lt;/span&gt;
 &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;rate&lt;/span&gt;
    &lt;span class="attribute"&gt;@place&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Place&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;find&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:id&lt;/span&gt;&lt;span class="punct"&gt;])&lt;/span&gt;
    &lt;span class="ident"&gt;rating&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:rate&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;to_i&lt;/span&gt;
    &lt;span class="attribute"&gt;@place&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;rate&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;rating&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;current_user&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;person&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;

    &lt;span class="ident"&gt;respond_to&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;format&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
      &lt;span class="ident"&gt;format&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;html&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="ident"&gt;redirect_to&lt;/span&gt; &lt;span class="symbol"&gt;:back&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
      &lt;span class="ident"&gt;format&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;xml&lt;/span&gt;  &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="ident"&gt;head&lt;/span&gt; &lt;span class="symbol"&gt;:ok&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="comment"&gt;# code snippets from the application helper above&lt;/span&gt;
&lt;span class="comment"&gt;# get the named route to use in this case rate_place_path&lt;/span&gt;
&lt;span class="ident"&gt;url_meth&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;rate_&lt;span class="expr"&gt;#{obj_type}&lt;/span&gt;_path&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;.&lt;/span&gt;&lt;span class="ident"&gt;to_sym&lt;/span&gt;

&lt;span class="punct"&gt;...&lt;/span&gt;

&lt;span class="comment"&gt;# generate the named route, equivalent to &lt;/span&gt;
&lt;span class="comment"&gt;# rate_place_path(:id =&amp;gt; id, :rate =&amp;gt; 1)&lt;/span&gt;

&lt;span class="ident"&gt;send&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;url_meth&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt;&lt;span class="symbol"&gt;:id&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:rate&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;})&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;One last thing slightly on topic, I added the following to the
acts_as_rated.rb file so I could get a list of the top rated articles,
seemed like a logical thing that anyone would want to do ;)&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="comment"&gt;# Find the top rated items, ordered by average rating&lt;/span&gt;
&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;find_top_rated&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;limit&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="constant"&gt;nil&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="ident"&gt;rating_class&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;acts_as_rated_options&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:rating_class&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;constantize&lt;/span&gt;
  &lt;span class="ident"&gt;base_sql&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="constant"&gt;EOS&lt;/span&gt;&lt;span class="string"&gt;
    select &lt;span class="expr"&gt;#{table_name}&lt;/span&gt;.*,COALESCE(average,0) AS rating_average from &lt;span class="expr"&gt;#{table_name}&lt;/span&gt; left outer join
      (select avg(rating) as average, rated_id  
         from &lt;span class="expr"&gt;#{rating_class.table_name}&lt;/span&gt;
         where rated_type = '&lt;span class="expr"&gt;#{class_name}&lt;/span&gt;' 
         group by rated_id) as rated 
         on rated_id=id 
       order by rating_average DESC
&lt;/span&gt;&lt;span class="constant"&gt;  EOS&lt;/span&gt;
  &lt;span class="ident"&gt;base_sql&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt; LIMIT &lt;span class="expr"&gt;#{limit}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;limit&lt;/span&gt;
  &lt;span class="ident"&gt;find_by_sql&lt;/span&gt; &lt;span class="ident"&gt;base_sql&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I hope this helps others trying the same thing, as always comments and
code improvements always welcome.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://technorati.com/tag/acts_as_rated" rel="tag"&gt;&lt;/a&gt;
&lt;a href="http://technorati.com/tag/rating+stars" rel="tag"&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Sat, 23 Jun 2007 13:49:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:7f42c5f4-c27c-42d6-b628-8ce190f5bed6</guid>
      <author>Jim Morris</author>
      <link>http://blog.wolfman.com/articles/2007/06/23/developing-a-social-networking-site-part-2-rating-stars</link>
      <category>Rails</category>
      <category>rails</category>
      <category>acts_as_rated</category>
      <category>stars</category>
      <category>rating</category>
      <trackback:ping>http://blog.wolfman.com/articles/trackback/317</trackback:ping>
    </item>
    <item>
      <title>"Developing a social networking site part 2 - rating stars" by wolfmanjm</title>
      <description>&lt;p&gt;I think the &lt;code&gt;act_as_rated&lt;/code&gt; plugin has several schemes for the ratings, and one is to keep them in a table rather than calculate them each time, It should be easy to use that option instead of the calculate every time I use here.&lt;/p&gt;</description>
      <pubDate>Wed, 09 Jul 2008 13:37:42 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:be24c95b-1130-44a3-a0c8-152936e1835a</guid>
      <link>http://blog.wolfman.com/articles/2007/06/23/developing-a-social-networking-site-part-2-rating-stars#comment-224</link>
    </item>
    <item>
      <title>"Developing a social networking site part 2 - rating stars" by Tom</title>
      <description>&lt;p&gt;Has anyone tried to cache the ratings?
I have a product search screen, and recalculating the rates is expensive, so I was thinking  either caching the rates in the database, or fragment cache.&lt;/p&gt;

&lt;p&gt;Any cool ideas?&lt;/p&gt;</description>
      <pubDate>Wed, 09 Jul 2008 13:25:39 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:3250af0d-6b8a-464e-babd-4e53f7758d29</guid>
      <link>http://blog.wolfman.com/articles/2007/06/23/developing-a-social-networking-site-part-2-rating-stars#comment-223</link>
    </item>
    <item>
      <title>"Developing a social networking site part 2 - rating stars" by Zach</title>
      <description>&lt;p&gt;OH HAI! Awesome little tutorial/plugin/I-don't-know here :) I solved &lt;a href="mailto:abenamer@yahoo.com" rel="nofollow"&gt;abenamer@yahoo.com&lt;/a&gt;'s problem. It originates in the controller in your rate definition, specifically:
&lt;code&gt;
@landlord.rate(rating, current_user.person)
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;As you said, you used person instead of user, but it might have been vague. Regardless, you need to use something like:
&lt;code&gt;
@landlord.rate(rating, current_user)
&lt;/code&gt;
if you are using the standard user system.&lt;/p&gt;

&lt;p&gt;That is all. &lt;/p&gt;</description>
      <pubDate>Fri, 23 May 2008 12:36:12 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:d973e6dc-c3b9-44e1-bc02-c9f365873f89</guid>
      <link>http://blog.wolfman.com/articles/2007/06/23/developing-a-social-networking-site-part-2-rating-stars#comment-216</link>
    </item>
    <item>
      <title>"Developing a social networking site part 2 - rating stars" by wolfmanjm</title>
      <description>&lt;p&gt;no, but then the code is pretty old, and newer versions of rails and/or acts_as_rated may have changed something, and I haven't upgraded either as the current versions work well enough.
If you find the solution please post here.&lt;/p&gt;

&lt;p&gt;thanks&lt;/p&gt;</description>
      <pubDate>Mon, 25 Feb 2008 15:29:06 -0800</pubDate>
      <guid isPermaLink="false">urn:uuid:0d139a6c-d736-469d-af94-cdb473e17a12</guid>
      <link>http://blog.wolfman.com/articles/2007/06/23/developing-a-social-networking-site-part-2-rating-stars#comment-204</link>
    </item>
    <item>
      <title>"Developing a social networking site part 2 - rating stars" by abenamer@yahoo.com</title>
      <description>&lt;p&gt;Hi there, I'm using this same code but I keep getting this error:&lt;/p&gt;

&lt;p&gt;"the rater object must be the one used when defining acts_as_rated (or a descendent of it). other objects are not acceptable"&lt;/p&gt;

&lt;p&gt;Did you encounter this error when you were writing this example?&lt;/p&gt;</description>
      <pubDate>Mon, 25 Feb 2008 15:23:29 -0800</pubDate>
      <guid isPermaLink="false">urn:uuid:b7a409d2-1217-4dfe-baf1-f191396b75e8</guid>
      <link>http://blog.wolfman.com/articles/2007/06/23/developing-a-social-networking-site-part-2-rating-stars#comment-203</link>
    </item>
    <item>
      <title>"Developing a social networking site part 2 - rating stars" by wolfmanjm</title>
      <description>&lt;p&gt;Good catch I'll update the code above
Thanks&lt;/p&gt;</description>
      <pubDate>Tue, 26 Jun 2007 22:57:01 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:9611e1dc-b22e-4076-9be5-04bdf5bfefd4</guid>
      <link>http://blog.wolfman.com/articles/2007/06/23/developing-a-social-networking-site-part-2-rating-stars#comment-4</link>
    </item>
    <item>
      <title>"Developing a social networking site part 2 - rating stars" by s01ipsist</title>
      <description>&lt;p&gt;Great work!
If the object hasn't been rated it can't have an average rating. 
Changing&lt;code&gt;o.rating_average&lt;/code&gt; to 0 in the below code saves me a sql call (I'm using the stats table)
r= "Not yet Rated"
r += &lt;code&gt;star_rating(o.rating_average, o_type, o.id, can_rate)&lt;/code&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 26 Jun 2007 22:32:36 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:c53274ad-3867-4894-a17a-db7549b60693</guid>
      <link>http://blog.wolfman.com/articles/2007/06/23/developing-a-social-networking-site-part-2-rating-stars#comment-3</link>
    </item>
    <item>
      <title>"Developing a social networking site part 2 - rating stars" by Jonathan</title>
      <description>&lt;p&gt;Dude, I Love You!!!&lt;/p&gt;

&lt;p&gt;I've been slacking on adding the stars rating to my rails project, but you just gave me a butt kick on getting that rolling.  Thanks!&lt;/p&gt;</description>
      <pubDate>Mon, 25 Jun 2007 21:09:47 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:7fdc3b66-4798-48b6-90fa-03085124bffb</guid>
      <link>http://blog.wolfman.com/articles/2007/06/23/developing-a-social-networking-site-part-2-rating-stars#comment-68</link>
    </item>
    <item>
      <title>"Developing a social networking site part 2 - rating stars" by topfunky</title>
      <description>&lt;p&gt;Maybe you could overlay a line graph on top of the stars.&lt;/p&gt;

&lt;p&gt;Or, just display the two graphs side-by-side.&lt;/p&gt;</description>
      <pubDate>Sun, 24 Jun 2007 11:39:42 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:8d5e5210-2e4e-4a32-af26-99c35a25a768</guid>
      <link>http://blog.wolfman.com/articles/2007/06/23/developing-a-social-networking-site-part-2-rating-stars#comment-16</link>
    </item>
    <item>
      <title>"Developing a social networking site part 2 - rating stars" by wolfmanjm</title>
      <description>&lt;p&gt;Thats interesting, the engineer in me likes the concept ;) it would be nice to combine the rating and the number of people who rated it in one graphic, but then I never was any good at UI design.&lt;/p&gt;</description>
      <pubDate>Sat, 23 Jun 2007 16:23:49 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:3be45dd9-52bc-429a-80b0-85f71c5681ca</guid>
      <link>http://blog.wolfman.com/articles/2007/06/23/developing-a-social-networking-site-part-2-rating-stars#comment-81</link>
    </item>
    <item>
      <title>"Developing a social networking site part 2 - rating stars" by topfunky</title>
      <description>&lt;p&gt;I have to take this opportunity to mention one of the worst implementations of star rating I've seen.&lt;/p&gt;

&lt;p&gt;Someone felt that the basic 5 stars wasn't good enough and decided to make a spectrum that reflects the percentage of votes for each rating. The result is a very confusing graphic.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.summize.com/about.html" rel="nofollow"&gt;http://www.summize.com/about.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In &lt;em&gt;Information Dashboard Design&lt;/em&gt;, Stephen Few mentions the kinds of graphical differentiation our minds can understand at first glance. Comparing several widths spread horizontally isn't one of them.&lt;/p&gt;

&lt;p&gt;Sometimes it's better to stick with a widely-used meme that people understand!&lt;/p&gt;</description>
      <pubDate>Sat, 23 Jun 2007 16:04:28 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:7973b072-2152-46f0-ae61-c0633097e981</guid>
      <link>http://blog.wolfman.com/articles/2007/06/23/developing-a-social-networking-site-part-2-rating-stars#comment-80</link>
    </item>
  </channel>
</rss>
