rateable 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.rdoc +83 -0
- data/Rakefile +2 -0
- data/app/coffeescripts/rateable.coffee +17 -0
- data/app/views/rateable/_rate.erb +7 -0
- data/app/views/rateable/_rating.erb +7 -0
- data/lib/generators/rateable/USAGE +1 -0
- data/lib/generators/rateable/rateable_generator.rb +23 -0
- data/lib/generators/rateable/templates/migration.rb +15 -0
- data/lib/generators/rateable/templates/rateable.css +22 -0
- data/lib/generators/rateable/templates/rateable.js +29 -0
- data/lib/generators/rateable/templates/star_filled.png +0 -0
- data/lib/generators/rateable/templates/star_unfilled.png +0 -0
- data/lib/rateable/helper.rb +14 -0
- data/lib/rateable/is_rateable.rb +33 -0
- data/lib/rateable/rate.rb +10 -0
- data/lib/rateable/rater.rb +32 -0
- data/lib/rateable/version.rb +3 -0
- data/lib/rateable.rb +21 -0
- data/rateable.gemspec +22 -0
- metadata +117 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
= Rateable
|
2
|
+
|
3
|
+
This is my own simple way to add ajax voting to a rails application.
|
4
|
+
|
5
|
+
== Installation
|
6
|
+
|
7
|
+
Add the Gem to your Gemfile
|
8
|
+
|
9
|
+
gem "glynx_rateable"
|
10
|
+
|
11
|
+
Then install the Gem
|
12
|
+
|
13
|
+
bundle install
|
14
|
+
|
15
|
+
=== Generating Files
|
16
|
+
|
17
|
+
After installing you should generate the needed files
|
18
|
+
|
19
|
+
rails generate rateable
|
20
|
+
|
21
|
+
=== Migrating
|
22
|
+
|
23
|
+
Then apply the migration to your Database
|
24
|
+
|
25
|
+
rake db:migrate
|
26
|
+
|
27
|
+
=== Includes
|
28
|
+
|
29
|
+
Add the "rateable.css" and "rateable.js" to the includes in your layout file
|
30
|
+
|
31
|
+
== Usage
|
32
|
+
|
33
|
+
=== Model
|
34
|
+
|
35
|
+
Add to the user model that should be able to rate things:
|
36
|
+
|
37
|
+
class User < ActiveRecord::Base
|
38
|
+
is_rater
|
39
|
+
end
|
40
|
+
|
41
|
+
Add to the model that should be rateable
|
42
|
+
|
43
|
+
class Model < ActiveRecord::Base
|
44
|
+
is_rateable
|
45
|
+
end
|
46
|
+
|
47
|
+
=== Controller
|
48
|
+
|
49
|
+
Add a rate action to the controller of the model that should be rateable, it should look like this:
|
50
|
+
|
51
|
+
def rate
|
52
|
+
# Check if the current user has already voted
|
53
|
+
if current_user and current_user.ratings.where(:rateable => @model).empty?
|
54
|
+
@model.rate(current_user, params[:stars])
|
55
|
+
render :partial => "rateable/rating", :locals => {:rating => @model.ratings.average("stars").to_i}
|
56
|
+
else
|
57
|
+
render :text => "You have already voted for this item!", :status => 500
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
=== Routes
|
62
|
+
|
63
|
+
Add a post action called "rate" to the resource in your "config/routes.rb"
|
64
|
+
|
65
|
+
resource :models do
|
66
|
+
member do
|
67
|
+
post :rate
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
=== Views
|
72
|
+
|
73
|
+
In your Views you can add the rating stars by adding:
|
74
|
+
|
75
|
+
<%= rating_for @model %>
|
76
|
+
|
77
|
+
You can also supply the url for the rate action manually, for example when using nested resources
|
78
|
+
|
79
|
+
<%= rating_for @model, :url => url_for([:rate, @category, @model]) %>
|
80
|
+
|
81
|
+
If there is no current_user method you can also supply your current user like this:
|
82
|
+
|
83
|
+
<%= rating_for @model, :user => @user %>
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
rate = (star) ->
|
2
|
+
url = star.data()["url"]
|
3
|
+
stars = star.data()["stars"]
|
4
|
+
$.ajax url,
|
5
|
+
type: "POST"
|
6
|
+
data:
|
7
|
+
stars : stars
|
8
|
+
dataType: "html"
|
9
|
+
error: (resp) ->
|
10
|
+
window.reload()
|
11
|
+
success: (resp) ->
|
12
|
+
star.parent().replaceWith(resp)
|
13
|
+
|
14
|
+
jQuery ->
|
15
|
+
$(".rating a").bind "click", (e) ->
|
16
|
+
rate $(this)
|
17
|
+
e.preventDefault()
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<% url ||= [:rate, rateable] %>
|
2
|
+
<% stars ||= 5 %>
|
3
|
+
<div class="rating" style="width: <%= stars*32 %>px;">
|
4
|
+
<% stars.times do |i| %>
|
5
|
+
<a class="rate" href="#" data-stars="<%=i+1%>" data-url="<%= url %>" style="width:<%=(i+1)*32%>px; z-index: <%= stars - i%>;"></a>
|
6
|
+
<% end %>
|
7
|
+
</div>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<% stars ||= 5 %>
|
2
|
+
<% tooltip ||= nil %>
|
3
|
+
<div class="rating" style="width: <%=stars*32%>px;" <%= "title='#{tooltip}'" if tooltip %> >
|
4
|
+
<% stars.times do |i| %>
|
5
|
+
<%= image_tag (i < rating ? "rateable/star_filled.png" : "rateable/star_unfilled.png"), :style => "margin-left: #{i*32}px; z-index: #{stars - i}" %>
|
6
|
+
<% end %>
|
7
|
+
</div>
|
@@ -0,0 +1 @@
|
|
1
|
+
This generates all files nessesary for using the rateable gem, including the migration.
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rails/generators/migration'
|
2
|
+
|
3
|
+
class RateableGenerator < Rails::Generators::Base
|
4
|
+
include Rails::Generators::Migration
|
5
|
+
|
6
|
+
source_root File.expand_path('../templates', __FILE__)
|
7
|
+
|
8
|
+
def copy_files
|
9
|
+
copy_file "star_unfilled.png", "public/images/rateable/star_unfilled.png"
|
10
|
+
copy_file "star_filled.png", "public/images/rateable/star_filled.png"
|
11
|
+
copy_file "rateable.js", "public/javascripts/rateable.js"
|
12
|
+
copy_file "rateable.css", "public/stylesheets/rateable.css"
|
13
|
+
migration_template "migration.rb", "db/migrate/rateable_migration"
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.next_migration_number(dirname)
|
17
|
+
if ActiveRecord::Base.timestamped_migrations
|
18
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
19
|
+
else
|
20
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class RateableMigration < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :rates do |t|
|
4
|
+
t.integer 'rateable_id'
|
5
|
+
t.string 'rateable_type'
|
6
|
+
t.integer 'rater_id'
|
7
|
+
t.string 'rater_type'
|
8
|
+
t.integer 'stars'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.down
|
13
|
+
drop_table :rates
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
.rating {
|
2
|
+
position: relative;
|
3
|
+
height: 32px;
|
4
|
+
background: url(/images/rateable/star_unfilled.png) top left repeat-x;
|
5
|
+
}
|
6
|
+
|
7
|
+
.rating a {
|
8
|
+
position: absolute;
|
9
|
+
height: 32px;
|
10
|
+
text-decoration: none;
|
11
|
+
}
|
12
|
+
|
13
|
+
.rating img {
|
14
|
+
position: absolute;
|
15
|
+
width: 32px;
|
16
|
+
text-decoration: none;
|
17
|
+
}
|
18
|
+
|
19
|
+
|
20
|
+
.rating .rate:hover {
|
21
|
+
background: url(/images/rateable/star_filled.png) bottom left repeat-x;
|
22
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
/* DO NOT MODIFY. This file was compiled Fri, 05 Aug 2011 22:17:18 GMT from
|
2
|
+
* /home/andre/Dokumente/yvi/comics/app/coffeescripts/rateable.coffee
|
3
|
+
*/
|
4
|
+
|
5
|
+
var rate;
|
6
|
+
rate = function(star) {
|
7
|
+
var stars, url;
|
8
|
+
url = star.data()["url"];
|
9
|
+
stars = star.data()["stars"];
|
10
|
+
return $.ajax(url, {
|
11
|
+
type: "POST",
|
12
|
+
data: {
|
13
|
+
stars: stars
|
14
|
+
},
|
15
|
+
dataType: "html",
|
16
|
+
error: function(resp) {
|
17
|
+
return window.reload();
|
18
|
+
},
|
19
|
+
success: function(resp) {
|
20
|
+
return star.parent().replaceWith(resp);
|
21
|
+
}
|
22
|
+
});
|
23
|
+
};
|
24
|
+
jQuery(function() {
|
25
|
+
return $(".rating a").bind("click", function(e) {
|
26
|
+
rate($(this));
|
27
|
+
return e.preventDefault();
|
28
|
+
});
|
29
|
+
});
|
Binary file
|
Binary file
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Rateable
|
2
|
+
module Helper
|
3
|
+
def rating_for(rateable, args = {})
|
4
|
+
user = args[:user] || try(:current_user)
|
5
|
+
if user and user.ratings.where(:rateable => rateable).empty?
|
6
|
+
render :partial => "rateable/rate", :locals => {:url => args[:url] ? args[:url] : url_for(rateable), :stars => args[:stars]}
|
7
|
+
else
|
8
|
+
stars_average = rateable.ratings.average("stars")
|
9
|
+
ratings_count = rateable.ratings.count
|
10
|
+
render :partial => "rateable/rating", :locals => {:stars => args[:stars], :rating => stars_average.to_i, :tooltip => "#{ratings_count} #{ratings_count == 1 ? "time" : "times"} rated, with an average value of #{stars_average}."}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Rateable
|
2
|
+
module IsRateable
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def is_rateable
|
9
|
+
has_many :ratings, :as => :rateable, :class_name => "Rateable::Rate", :dependent => :destroy
|
10
|
+
include Rateable::IsRateable::InstanceMethods
|
11
|
+
end
|
12
|
+
|
13
|
+
def is_rateable?
|
14
|
+
true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module InstanceMethods
|
19
|
+
def is_rateable?
|
20
|
+
true
|
21
|
+
end
|
22
|
+
|
23
|
+
# include instance methods that are needed
|
24
|
+
def rate(user,stars)
|
25
|
+
rating = Rate.where(:rateable => self, :rater => user).first
|
26
|
+
rating = Rate.create(:rateable => self, :rater => user) unless rating
|
27
|
+
rating.stars = stars
|
28
|
+
rating.save
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Rateable
|
2
|
+
class Rate < ActiveRecord::Base
|
3
|
+
belongs_to :rateable, :polymorphic => true
|
4
|
+
belongs_to :rater, :polymorphic => true
|
5
|
+
|
6
|
+
validates_presence_of :rateable
|
7
|
+
validates_presence_of :rater
|
8
|
+
validates_inclusion_of :stars, :in => (1..5).to_a
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Rateable
|
2
|
+
module Rater
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def is_rater
|
9
|
+
has_many :ratings, :as => :rater, :class_name => "Rateable::Rate", :dependent => :destroy
|
10
|
+
include Rateable::Rater::InstanceMethods
|
11
|
+
end
|
12
|
+
|
13
|
+
def is_rater?
|
14
|
+
true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module InstanceMethods
|
19
|
+
def is_rater?
|
20
|
+
true
|
21
|
+
end
|
22
|
+
|
23
|
+
def rate(obj,stars)
|
24
|
+
if obj.is_rateable?
|
25
|
+
obj.rate(self,stars)
|
26
|
+
else
|
27
|
+
false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/rateable.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require "active_record"
|
2
|
+
require "action_view"
|
3
|
+
require "action_controller"
|
4
|
+
|
5
|
+
require 'rateable/is_rateable'
|
6
|
+
require 'rateable/rater'
|
7
|
+
require 'rateable/rate'
|
8
|
+
|
9
|
+
if defined?(ActiveRecord::Base)
|
10
|
+
ActiveRecord::Base.send :include, Rateable::IsRateable
|
11
|
+
ActiveRecord::Base.send :include, Rateable::Rater
|
12
|
+
end
|
13
|
+
|
14
|
+
if defined?(ActionView::Base)
|
15
|
+
require 'rateable/helper'
|
16
|
+
ActionView::Base.send :include, Rateable::Helper
|
17
|
+
end
|
18
|
+
|
19
|
+
if defined?(ActionController::Base)
|
20
|
+
ActionController::Base.prepend_view_path File.dirname(__FILE__) + "/../app/views"
|
21
|
+
end
|
data/rateable.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "rateable/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "rateable"
|
7
|
+
s.version = Rateable::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["André Domnick"]
|
10
|
+
s.email = ["andre@paniccrew.de"]
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = %q{Add a stars rating to your models}
|
13
|
+
s.description = %q{A way for simply adding an ajax rating to any of your models}
|
14
|
+
|
15
|
+
s.add_runtime_dependency 'rails', ">= 3.0.0"
|
16
|
+
s.add_runtime_dependency 'activerecord', ">= 3.0.0"
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rateable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 17
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 7
|
10
|
+
version: 0.0.7
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- "Andr\xC3\xA9 Domnick"
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-08-06 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rails
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 7
|
29
|
+
segments:
|
30
|
+
- 3
|
31
|
+
- 0
|
32
|
+
- 0
|
33
|
+
version: 3.0.0
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: activerecord
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 7
|
45
|
+
segments:
|
46
|
+
- 3
|
47
|
+
- 0
|
48
|
+
- 0
|
49
|
+
version: 3.0.0
|
50
|
+
type: :runtime
|
51
|
+
version_requirements: *id002
|
52
|
+
description: A way for simply adding an ajax rating to any of your models
|
53
|
+
email:
|
54
|
+
- andre@paniccrew.de
|
55
|
+
executables: []
|
56
|
+
|
57
|
+
extensions: []
|
58
|
+
|
59
|
+
extra_rdoc_files: []
|
60
|
+
|
61
|
+
files:
|
62
|
+
- .gitignore
|
63
|
+
- Gemfile
|
64
|
+
- README.rdoc
|
65
|
+
- Rakefile
|
66
|
+
- app/coffeescripts/rateable.coffee
|
67
|
+
- app/views/rateable/_rate.erb
|
68
|
+
- app/views/rateable/_rating.erb
|
69
|
+
- lib/generators/rateable/USAGE
|
70
|
+
- lib/generators/rateable/rateable_generator.rb
|
71
|
+
- lib/generators/rateable/templates/migration.rb
|
72
|
+
- lib/generators/rateable/templates/rateable.css
|
73
|
+
- lib/generators/rateable/templates/rateable.js
|
74
|
+
- lib/generators/rateable/templates/star_filled.png
|
75
|
+
- lib/generators/rateable/templates/star_unfilled.png
|
76
|
+
- lib/rateable.rb
|
77
|
+
- lib/rateable/helper.rb
|
78
|
+
- lib/rateable/is_rateable.rb
|
79
|
+
- lib/rateable/rate.rb
|
80
|
+
- lib/rateable/rater.rb
|
81
|
+
- lib/rateable/version.rb
|
82
|
+
- rateable.gemspec
|
83
|
+
homepage: ""
|
84
|
+
licenses: []
|
85
|
+
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
|
89
|
+
require_paths:
|
90
|
+
- lib
|
91
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
hash: 3
|
97
|
+
segments:
|
98
|
+
- 0
|
99
|
+
version: "0"
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
none: false
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
hash: 3
|
106
|
+
segments:
|
107
|
+
- 0
|
108
|
+
version: "0"
|
109
|
+
requirements: []
|
110
|
+
|
111
|
+
rubyforge_project:
|
112
|
+
rubygems_version: 1.8.7
|
113
|
+
signing_key:
|
114
|
+
specification_version: 3
|
115
|
+
summary: Add a stars rating to your models
|
116
|
+
test_files: []
|
117
|
+
|