Permalink
Browse files

Added view helper

  • Loading branch information...
1 parent 41594f2 commit 686e94f7a99e7f7b21fa096d14af96008f5383b5 @fnando committed Oct 11, 2008
Showing with 126 additions and 16 deletions.
  1. +72 −0 README.markdown
  2. +2 −1 init.rb
  3. +52 −15 lib/has_ratings.rb
View
@@ -93,6 +93,78 @@ you can paginate the users that rated a given item:
photo.find_users_that_rated(:page => 2)
+Use this view helper to display the rating system:
+
+ <%= rating_stars photo, current_user, rate_photo_path(photo) %>
+
+Is based on [this article](http://www.thebroth.com/blog/119). You can get the
+stars image at <http://f.simplesideias.com.br/stars.gif>. The CSS you need:
+
+ ul.rating {
+ width: 80px;
+ height: 16px;
+ margin: 0 10px 0 0;
+ padding: 0;
+ list-style: none;
+ float:left;
+ position: relative;
+ background: url(../images/stars.gif) no-repeat 0 0;
+ }
+
+ ul.none { background-position: 0 0; }
+ ul.half { background-position: 0 -16px; }
+ ul.one { background-position: 0 -32px; }
+ ul.one-half { background-position: 0 -48px; }
+ ul.two { background-position: 0 -64px; }
+ ul.two-half { background-position: 0 -80px; }
+ ul.three { background-position: 0 -96px; }
+ ul.three-half { background-position: 0 -112px; }
+ ul.four { background-position: 0 -128px; }
+ ul.four-half { background-position: 0 -144px; }
+ ul.five { background-position: 0 -160px; }
+
+ ul.rating li {
+ cursor: pointer;
+ float: left;
+ text-indent: -999em;
+ }
+
+ ul.rated li {
+ cursor: default;
+ }
+
+ ul.rating li a,
+ ul.rating li span {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 16px;
+ height: 16px;
+ text-decoration: none;
+ z-index: 200;
+ }
+
+ ul.rating li.one a, ul.rating li.one span { left:0; }
+ ul.rating li.two a, ul.rating li.two span { left:16px; }
+ ul.rating li.three a, ul.rating li.three span { left:32px; }
+ ul.rating li.four a, ul.rating li.four span { left:48px; }
+ ul.rating li.five a, ul.rating li.five span { left:64px; }
+
+ ul.rating li a:hover {
+ z-index: 2;
+ width: 80px;
+ height: 16px;
+ overflow: hidden;
+ left: 0;
+ background: url(../images/stars.gif) no-repeat 0 0
+ }
+
+ ul.rating li.one a:hover { background-position:0 -176px; }
+ ul.rating li.two a:hover { background-position:0 -192px; }
+ ul.rating li.three a:hover { background-position:0 -208px; }
+ ul.rating li.four a:hover { background-position:0 -224px; }
+ ul.rating li.five a:hover { background-position:0 -240px; }
+
NOTE: You should have a User model. Otherwise, **this won't work**!
Copyright (c) 2008 Nando Vieira, released under the MIT license
View
@@ -1,4 +1,5 @@
require "has_ratings"
-ActiveRecord::Base.send(:include, SimplesIdeias::Acts::Ratings)
+ActiveRecord::Base.send(:include, SimplesIdeias::Ratings::ActiveRecord)
+ActionView::Base.send(:include, SimplesIdeias::Ratings::ActionView)
require File.dirname(__FILE__) + "/lib/rating"
View
@@ -1,41 +1,78 @@
module SimplesIdeias
- module Acts
- module Ratings
- def self.included(base)
- base.extend SimplesIdeias::Acts::Ratings::ClassMethods
+ module Ratings
+ module ActionView
+ def rating_stars(object, user, url)
+ rating = object.rating
+ css_names = %w(zero one two three four five)
+ css_rating = css_names[rating.to_i]
+ diff = ('%.1f' % (rating.to_f - rating.to_i)).to_f
+
+ if (0.1..0.5).include?(diff)
+ css_rating << '-half'
+ elsif (0.6..0.9).include?(diff)
+ css_rating = css_names[rating.to_i + 1]
+ end
+ if object.rated?(user)
+ %(
+ <ul class="rating #{css_rating} rated">
+ <li class="one"><span>1</span></li>
+ <li class="two"><span>2</span></li>
+ <li class="three"><span>3</span></li>
+ <li class="four"><span>4</span></li>
+ <li class="five"><span>5</span></li>
+ </ul>
+ )
+ else
+ %(
+ <ul class="rating #{css_rating}">
+ <li class="one"><a href="#{url}?r=1" title="1 Star" rel="no-follow">1</a></li>
+ <li class="two"><a href="#{url}?r=2" title="2 Stars" rel="no-follow">2</a></li>
+ <li class="three"><a href="#{url}?r=3" title="3 Stars" rel="no-follow">3</a></li>
+ <li class="four"><a href="#{url}?r=4" title="4 Stars" rel="no-follow">4</a></li>
+ <li class="five"><a href="#{url}?r=5" title="5 Stars" rel="no-follow">5</a></li>
+ </ul>
+ )
+ end
+ end
+ end
+
+ module ActiveRecord
+ def self.included(base)
+ base.extend SimplesIdeias::Ratings::ActiveRecord::ClassMethods
+
class << base
attr_accessor :has_rating_options
end
end
-
+
module ClassMethods
def has_ratings
- include SimplesIdeias::Acts::Ratings::InstanceMethods
-
+ include SimplesIdeias::Ratings::ActiveRecord::InstanceMethods
+
self.has_rating_options = {
- :type => ActiveRecord::Base.send(:class_name_of_active_record_descendant, self).to_s
+ :type => ::ActiveRecord::Base.send(:class_name_of_active_record_descendant, self).to_s
}
-
+
# associations
has_many :ratings, :as => :rateable, :dependent => :destroy
-
+
# named scopes
named_scope :best_rated, :order => 'rating desc'
named_scope :most_rated, :order => 'ratings_count desc'
end
end
-
+
module InstanceMethods
def rated?(owner)
!find_rating_by_user(owner).nil?
end
-
+
def find_rating_by_user(owner)
owner = owner.id if owner.is_a?(User)
self.ratings.find(:first, :conditions => {:user_id => owner})
end
-
+
def rating!
Rating.average(:rating, {
:conditions => {
@@ -44,12 +81,12 @@ def rating!
}
})
end
-
+
def rate(options)
options[:user_id] = options.delete(:user).id if options[:user]
self.ratings.create(options)
end
-
+
def find_users_that_rated(options={})
options = {
:limit => 10,

0 comments on commit 686e94f

Please sign in to comment.