acts_as_rateable 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +11 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +77 -0
- data/Rakefile +22 -0
- data/generators/acts_as_rateable_migration/acts_as_rateable_migration_generator.rb +7 -0
- data/generators/acts_as_rateable_migration/templates/migration.rb +24 -0
- data/generators/acts_as_rateable_update1/acts_as_rateable_update1_generator.rb +7 -0
- data/generators/acts_as_rateable_update1/templates/migration.rb +48 -0
- data/init.rb +1 -0
- data/lib/acts_as_rateable.rb +80 -0
- data/lib/rating.rb +21 -0
- data/lib/user_rating.rb +24 -0
- data/rails/init.rb +2 -0
- metadata +72 -0
data/CHANGELOG.rdoc
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
== 2.0 released 2009-7-22
|
2
|
+
|
3
|
+
* Refactored database structure for better performance: the average rating and ratings count are now pre-computed and updated when new ratings are recorded
|
4
|
+
* The API now requires consistently the user object instead of the user_id
|
5
|
+
* Added testing framework and unit tests
|
6
|
+
* Made available as ruby gem
|
7
|
+
|
8
|
+
== 1.0 released 2008
|
9
|
+
|
10
|
+
* The original acts_as_rateable plugin, first release by Ferenc Fekete
|
11
|
+
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2007 [name of plugin creator]
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
= Acts As Rateble
|
2
|
+
|
3
|
+
Acts_as_rateable is a rails plugin providing a rating interface for ActiveRecord models.
|
4
|
+
It is released under the MIT license.
|
5
|
+
The original plugin is used on cotcot.hu for article rating, sponsored quizzes, etc.
|
6
|
+
|
7
|
+
= Features
|
8
|
+
|
9
|
+
* Rating scores are recorded by user
|
10
|
+
* Users can update previous ratings
|
11
|
+
* Uses a polymorphic association to your model, so no changes to your existing models in the database are required
|
12
|
+
* Stores computed score and number of ratings for efficient data access
|
13
|
+
* Possibility to change range of the ratings (1..5 is default)
|
14
|
+
|
15
|
+
= Installation
|
16
|
+
|
17
|
+
== Install as gem (recommended)
|
18
|
+
|
19
|
+
Install as a gem:
|
20
|
+
|
21
|
+
$ sudo gem install mreinsch-acts_as_rateable
|
22
|
+
|
23
|
+
Then add the gem dependency in your config:
|
24
|
+
|
25
|
+
# config/environment.rb
|
26
|
+
config.gem "mreinsch-acts_as_rateable", :source => "http://gems.github.com", :lib => "acts_as_rateable"
|
27
|
+
|
28
|
+
== Install as plugin
|
29
|
+
|
30
|
+
To install as a plugin, use:
|
31
|
+
|
32
|
+
$ ./script/plugin install git://github.com/mreinsch/acts_as_rateable.git
|
33
|
+
|
34
|
+
= Example Usage
|
35
|
+
|
36
|
+
Install the plugin into your vendor/plugins directory, insert 'acts_as_rateable' into your model, then restart your application.
|
37
|
+
|
38
|
+
class Post < ActiveRecord::Base
|
39
|
+
acts_as_rateable
|
40
|
+
end
|
41
|
+
|
42
|
+
Now your model is extended by the plugin, you can rate it (1-#) or calculate the average rating.
|
43
|
+
|
44
|
+
@post.rate_it(4, current_user)
|
45
|
+
|
46
|
+
@post.average_rating #=> 4.0
|
47
|
+
@post.average_rating_round #=> 4
|
48
|
+
@post.average_rating_percent #=> 80
|
49
|
+
@post.rated_by?(current_user) #=> true
|
50
|
+
@post.rating_by(current_user) #=> 4
|
51
|
+
@post.ratings_couunt #=> 1
|
52
|
+
|
53
|
+
Post.find_top_rated #=> top rated records
|
54
|
+
|
55
|
+
Optional you can specify the highest score using the :max_rating paramter as follows. The default for :max_rating is 5.
|
56
|
+
|
57
|
+
class Comment < ActiveRecord::Base
|
58
|
+
acts_as_rateable :max_rating => 10
|
59
|
+
end
|
60
|
+
|
61
|
+
See acts_as_rateable.rb for further details!
|
62
|
+
|
63
|
+
= Updating
|
64
|
+
|
65
|
+
== Updating from Ferenc Fekete's acts_as_rateable v1.0
|
66
|
+
|
67
|
+
1. Remove the old plugin, and install this version.
|
68
|
+
1. Check your code and make sure you pass the user object instead of the user ID for the rate_it, rated_by? and rating_by methods.
|
69
|
+
1. Generate an update migration using: ./script/generate acts_as_rateable_update1
|
70
|
+
1. Run your test cases
|
71
|
+
|
72
|
+
|
73
|
+
= Copyright
|
74
|
+
|
75
|
+
Copyright (c) 2007 Ferenc Fekete, http://xpnindustries.com , released under the MIT license
|
76
|
+
|
77
|
+
Copyright (c) 2009 mobalean LLC, http://www.mobalean.com
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc 'Test the acts_as_ratable plugin.'
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.pattern = 'test/**/*_test.rb'
|
12
|
+
t.verbose = true
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Generate documentation for the acts_as_ratable plugin.'
|
16
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
18
|
+
rdoc.title = 'ActsAsRatable'
|
19
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
20
|
+
rdoc.rdoc_files.include('README.rdoc', 'CHANGELOG.rdoc')
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
22
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class ActsAsRateableMigration < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table "ratings" do |t|
|
4
|
+
t.references "rateable", :polymorphic => true, :nil => false
|
5
|
+
t.float "average_rating"
|
6
|
+
t.integer "ratings_count"
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
add_index "ratings", ["rateable_id", "rateable_type"]
|
10
|
+
|
11
|
+
create_table "user_ratings" do |t|
|
12
|
+
t.references "rating", :nil => false
|
13
|
+
t.references "user", :nil => false
|
14
|
+
t.integer "score", :nil => false
|
15
|
+
t.timestamps
|
16
|
+
end
|
17
|
+
add_index "user_ratings", ["user_id", "rating_id"]
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.down
|
21
|
+
drop_table "user_ratings"
|
22
|
+
drop_table "ratings"
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
class ActsAsRateableUpdate1 < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
rename_table "rates", "old_rates"
|
4
|
+
rename_table "ratings", "old_ratings"
|
5
|
+
|
6
|
+
create_table "ratings" do |t|
|
7
|
+
t.references "rateable", :polymorphic => true, :nil => false
|
8
|
+
t.float "average_rating"
|
9
|
+
t.integer "ratings_count"
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
add_index "ratings", ["rateable_id", "rateable_type"]
|
13
|
+
|
14
|
+
create_table "user_ratings" do |t|
|
15
|
+
t.references "rating", :nil => false
|
16
|
+
t.references "user", :nil => false
|
17
|
+
t.integer "score", :nil => false
|
18
|
+
t.timestamps
|
19
|
+
end
|
20
|
+
add_index "user_ratings", ["user_id", "rating_id"]
|
21
|
+
|
22
|
+
say_with_time "migrating exsting ratings" do
|
23
|
+
connection.transaction do
|
24
|
+
sql = "SELECT rateable_id, rateable_type, user_id, score, old_ratings.created_at, old_ratings.updated_at " +
|
25
|
+
"FROM old_ratings INNER JOIN old_rates ON old_ratings.rate_id = old_rates.id"
|
26
|
+
connection.select_all(sql).each do |row|
|
27
|
+
rating = Rating.find_or_create_by_rateable_id_and_rateable_type(
|
28
|
+
:rateable_id => row['rateable_id'],
|
29
|
+
:rateable_type => row['rateable_type'],
|
30
|
+
:created_at => row['created_at'])
|
31
|
+
rating.user_ratings.find_or_create_by_user_id(
|
32
|
+
:user_id => row['user_id'],
|
33
|
+
:score => row['score'],
|
34
|
+
:created_at => row['created_at'],
|
35
|
+
:updated_at => row['updated_at'])
|
36
|
+
end
|
37
|
+
Rating.find(:all).each {|rating| rating.update_rating }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
drop_table "old_rates"
|
42
|
+
drop_table "old_ratings"
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.down
|
46
|
+
raise ActiveRecord::IrreversibleMigration, "Can't recover old ratings tables"
|
47
|
+
end
|
48
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/rails/init.rb"
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Acts
|
3
|
+
module Rateable
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def acts_as_rateable(options = {})
|
10
|
+
has_one :rating, :as => :rateable, :dependent => :destroy
|
11
|
+
|
12
|
+
unless respond_to?(:max_rating)
|
13
|
+
class_inheritable_accessor :max_rating
|
14
|
+
attr_protected :max_rating
|
15
|
+
self.max_rating = options[:max_rating] || 5
|
16
|
+
end
|
17
|
+
|
18
|
+
include ActiveRecord::Acts::Rateable::ClassMethods
|
19
|
+
include ActiveRecord::Acts::Rateable::InstanceMethods
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module ClassMethods
|
24
|
+
# Returns the top rated records, ordered by their average rating.
|
25
|
+
# You can use the usual finder parameters to narrow down the records
|
26
|
+
# to return.
|
27
|
+
# The finder limits the number of returned records to 20 by default.
|
28
|
+
# Specify :limit to change it.
|
29
|
+
def find_top_rated(params = {})
|
30
|
+
find_params = params.merge(:include => :rating)
|
31
|
+
find_params[:order] = ['ratings.average_rating DESC', find_params.delete(:order)].compact.join(", ")
|
32
|
+
find_params[:limit] = 20 unless find_params.key?(:limit)
|
33
|
+
find(:all, find_params)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module InstanceMethods
|
38
|
+
# Rates the object by a given score. A user object should be passed to the method.
|
39
|
+
def rate_it(score, user)
|
40
|
+
create_rating unless rating
|
41
|
+
rating.rate(score, user)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns the average rating. Calculation based on the already given scores.
|
45
|
+
def average_rating
|
46
|
+
rating && rating.average_rating || 0.0
|
47
|
+
end
|
48
|
+
|
49
|
+
# Rounds the average rating value.
|
50
|
+
def average_rating_round
|
51
|
+
average_rating.round
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns the average rating in percent.
|
55
|
+
def average_rating_percent
|
56
|
+
f = 100 / max_rating.to_f
|
57
|
+
average_rating * f
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns the number of ratings.
|
61
|
+
def ratings_count
|
62
|
+
rating && rating.ratings_count || 0
|
63
|
+
end
|
64
|
+
|
65
|
+
# Checks whether a user rated the object or not.
|
66
|
+
def rated_by?(user)
|
67
|
+
rating && rating.user_ratings.exists?(:user_id => user)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Returns the rating a specific user has given the object.
|
71
|
+
def rating_by(user)
|
72
|
+
user_rating = rating && rating.user_ratings.find_by_user_id(user.id)
|
73
|
+
user_rating ? user_rating.score : nil
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/rating.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
class Rating < ActiveRecord::Base
|
2
|
+
belongs_to :rateable, :polymorphic => true
|
3
|
+
has_many :user_ratings
|
4
|
+
|
5
|
+
delegate :max_rating, :to => :rateable
|
6
|
+
|
7
|
+
def rate(score, user)
|
8
|
+
user_ratings.find_or_initialize_by_user_id(user.id).update_attributes!(:score => score)
|
9
|
+
reload
|
10
|
+
end
|
11
|
+
|
12
|
+
# Call this method the update the avarage rating; you don't normally need to
|
13
|
+
# do this manually, saving or updating a user rating already takes care of
|
14
|
+
# updating the avarage rating.
|
15
|
+
def update_rating
|
16
|
+
self.average_rating = user_ratings.average(:score)
|
17
|
+
self.ratings_count = user_ratings.count
|
18
|
+
save!
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
data/lib/user_rating.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
class UserRating < ActiveRecord::Base
|
2
|
+
belongs_to :rating
|
3
|
+
|
4
|
+
delegate :max_rating, :to => :rating
|
5
|
+
|
6
|
+
validates_presence_of :score
|
7
|
+
validates_uniqueness_of :user_id, :scope => :rating_id
|
8
|
+
validate :max_rating_allowed_by_parent
|
9
|
+
|
10
|
+
after_save do |user_rating|
|
11
|
+
user_rating.rating.update_rating
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def max_rating_allowed_by_parent
|
17
|
+
if score < 1
|
18
|
+
errors.add(:score, "must be greater than or equal to 1")
|
19
|
+
elsif score > max_rating
|
20
|
+
errors.add(:score, "must be less than or equal to #{max_rating}")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/rails/init.rb
ADDED
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: acts_as_rateable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ferenc Fekete
|
8
|
+
- Gabriel Gironda
|
9
|
+
- Michael Reinsch
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
|
14
|
+
date: 2009-09-23 00:00:00 +02:00
|
15
|
+
default_executable:
|
16
|
+
dependencies: []
|
17
|
+
|
18
|
+
description: Acts_as_rateable is a rails plugin providing a rating interface for ActiveRecord models.
|
19
|
+
email: michael@mobalean.com
|
20
|
+
executables: []
|
21
|
+
|
22
|
+
extensions: []
|
23
|
+
|
24
|
+
extra_rdoc_files:
|
25
|
+
- README.rdoc
|
26
|
+
- CHANGELOG.rdoc
|
27
|
+
- MIT-LICENSE
|
28
|
+
files:
|
29
|
+
- README.rdoc
|
30
|
+
- CHANGELOG.rdoc
|
31
|
+
- MIT-LICENSE
|
32
|
+
- Rakefile
|
33
|
+
- init.rb
|
34
|
+
- rails/init.rb
|
35
|
+
- lib/rating.rb
|
36
|
+
- lib/user_rating.rb
|
37
|
+
- lib/acts_as_rateable.rb
|
38
|
+
- generators/acts_as_rateable_update1/templates/migration.rb
|
39
|
+
- generators/acts_as_rateable_update1/acts_as_rateable_update1_generator.rb
|
40
|
+
- generators/acts_as_rateable_migration/templates/migration.rb
|
41
|
+
- generators/acts_as_rateable_migration/acts_as_rateable_migration_generator.rb
|
42
|
+
has_rdoc: true
|
43
|
+
homepage: http://github.com/mreinsch/acts_as_rateable
|
44
|
+
licenses: []
|
45
|
+
|
46
|
+
post_install_message:
|
47
|
+
rdoc_options:
|
48
|
+
- --main
|
49
|
+
- README.rdoc
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
version:
|
64
|
+
requirements: []
|
65
|
+
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 1.3.5
|
68
|
+
signing_key:
|
69
|
+
specification_version: 3
|
70
|
+
summary: Rails plugin providing a rating interface for ActiveRecord models
|
71
|
+
test_files: []
|
72
|
+
|