acts_as_rateable 2.0.1
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/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
|
+
|