mongoid_rateable 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +10 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +1 -1
- data/README.rdoc +30 -3
- data/VERSION +1 -1
- data/lib/mongoid_rateable/rateable.rb +116 -17
- data/mongoid_rateable.gemspec +6 -5
- data/spec/models/article.rb +1 -1
- data/spec/models/comment.rb +1 -1
- data/spec/rateable_spec.rb +4 -4
- metadata +6 -5
data/CHANGELOG.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
*0.3.0*
|
4
|
+
|
5
|
+
Removed RATING_RANGE constant.
|
6
|
+
The RATING_RANGE constant is very inflexible. Much better with a class method, since
|
7
|
+
it allows for reusability, definint the range in a module that is pulled into
|
8
|
+
several classes etc.
|
9
|
+
|
10
|
+
Instead this gem now includes several other config methods.
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/README.rdoc
CHANGED
@@ -15,18 +15,42 @@ Add to Gemfile:
|
|
15
15
|
|
16
16
|
== Getting Started
|
17
17
|
|
18
|
-
Include the module in models where you want it
|
18
|
+
Include the module in models where you want it.
|
19
|
+
There are many other configurtion variants available ;)
|
19
20
|
|
20
21
|
class Post
|
21
22
|
include Mongoid::Document
|
22
23
|
include Mongoid::Rateable
|
23
24
|
|
24
|
-
RATING_RANGE = (1..5) # Optional (if you need restriction)
|
25
25
|
...
|
26
26
|
end
|
27
27
|
|
28
|
-
|
28
|
+
or
|
29
|
+
|
30
|
+
class Post
|
29
31
|
include Mongoid::Document
|
32
|
+
include Mongoid::Rateable
|
33
|
+
|
34
|
+
# class method
|
35
|
+
def self.rating_range
|
36
|
+
(1..5) # should always return the same range
|
37
|
+
end
|
38
|
+
|
39
|
+
# Optional restriction
|
40
|
+
rateable_by User
|
41
|
+
|
42
|
+
...
|
43
|
+
end
|
44
|
+
|
45
|
+
or
|
46
|
+
|
47
|
+
class Post
|
48
|
+
include Mongoid::Document
|
49
|
+
include Mongoid::Rateable
|
50
|
+
|
51
|
+
# macro
|
52
|
+
set_rating_range (1..5)
|
53
|
+
rateable_by User, Admin
|
30
54
|
...
|
31
55
|
end
|
32
56
|
|
@@ -42,6 +66,9 @@ You can rate by passing an integer and a rater model to the "rate" method:
|
|
42
66
|
@post.rate 5, @user # I LOVE this!
|
43
67
|
@post.rate -10, @user # Delete it from the Internet!
|
44
68
|
|
69
|
+
# Many users love this!
|
70
|
+
@post.rate 5, @users # They LOVIN' it!
|
71
|
+
|
45
72
|
Rates have weight (1 by defaut)
|
46
73
|
|
47
74
|
@post.rate 5, @user, 3 # Rate @post with weight 3 (@user has high karma)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
@@ -20,29 +20,117 @@ module Mongoid
|
|
20
20
|
scope :highest_rated, ->(limit=10) { order_by([:rating, :desc]).limit(limit) }
|
21
21
|
end
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
23
|
+
module ClassMethods
|
24
|
+
def rater_classes
|
25
|
+
@rater_classes ||= []
|
26
|
+
end
|
27
|
+
|
28
|
+
def valid_rater_class? clazz
|
29
|
+
return true if !rater_classes || rater_classes.empty?
|
30
|
+
rater_classes.include? clazz
|
31
|
+
end
|
32
|
+
|
33
|
+
def in_rating_range?(value)
|
34
|
+
range = rating_range if respond_to?(:rating_range)
|
35
|
+
range ? range.include?(value.to_i) : true
|
36
|
+
end
|
37
|
+
|
38
|
+
# macro to create dynamic :rating_range class method!
|
39
|
+
# can now even take an Array and find the range of values!
|
40
|
+
def set_rating_range range = nil
|
41
|
+
raterange = case range
|
42
|
+
when Array
|
43
|
+
arr = range.sort
|
44
|
+
Range.new arr.first, arr.last
|
45
|
+
when Range
|
46
|
+
range
|
47
|
+
else
|
48
|
+
raise ArgumentError, "Must be a range, was: #{range}"
|
49
|
+
end
|
50
|
+
|
51
|
+
(class << self; self; end).send(:define_method, :rating_range) do
|
52
|
+
raterange
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def rateable_by *clazzes
|
57
|
+
@rater_classes = []
|
58
|
+
clazzes.each do |clazz|
|
59
|
+
raise ArgumentError, "A rateable must be a class, was: #{clazz}" unless clazz.respond_to?(:new)
|
60
|
+
@rater_classes << clazz
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def rate_config options = {}
|
65
|
+
set_rating_range options[:range]
|
66
|
+
rateable_by options[:raters]
|
67
|
+
end
|
68
|
+
|
69
|
+
def default_rater rater=nil, &block
|
70
|
+
case rater
|
71
|
+
when Symbol, String
|
72
|
+
define_method :default_rater do
|
73
|
+
self.send(rater) # fx to use owner or user relation
|
74
|
+
end
|
75
|
+
when nil
|
76
|
+
raise ArgumentError, "Must take symbol or block argument" unless block_defined?
|
77
|
+
define_method :default_rater do
|
78
|
+
self.instance_eval(&block)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end # class methods
|
83
|
+
|
84
|
+
def rate(mark, rater = nil, weight = 1)
|
85
|
+
case rater
|
86
|
+
when Array
|
87
|
+
rater.each{|rater| rate(mark, rater, weight)}
|
88
|
+
else
|
89
|
+
if !rater
|
90
|
+
unless respond_to?(:default_rater)
|
91
|
+
raise ArgumentError, "No rater argument and no default_rater specified"
|
92
|
+
end
|
93
|
+
rater = default_rater
|
94
|
+
end
|
95
|
+
validate_rater!(rater)
|
96
|
+
validate_rating!(mark)
|
97
|
+
unrate_without_rating_update(rater)
|
98
|
+
total_mark = mark.to_i*weight.to_i
|
99
|
+
self.rates += total_mark
|
100
|
+
self.rating_marks.new(:rater_id => rater.id, :mark => mark, :rater_class => rater.class.to_s, :weight => weight)
|
101
|
+
self.weighted_rate_count += weight
|
102
|
+
update_rating
|
103
|
+
end
|
31
104
|
end
|
32
105
|
|
33
106
|
def unrate(rater)
|
34
|
-
|
35
|
-
|
107
|
+
case rater
|
108
|
+
when Array
|
109
|
+
rater.each{|rater| unrate(mark, rater, weight)}
|
110
|
+
else
|
111
|
+
unrate_without_rating_update(rater)
|
112
|
+
update_rating
|
113
|
+
end
|
36
114
|
end
|
37
115
|
|
38
116
|
def rate_and_save(mark, rater, weight = 1)
|
39
|
-
|
40
|
-
|
117
|
+
case rater
|
118
|
+
when Array
|
119
|
+
rater.each{|rater| rate_and_save(mark, rater, weight)}
|
120
|
+
else
|
121
|
+
rate(mark, rater, weight)
|
122
|
+
save
|
123
|
+
end
|
41
124
|
end
|
42
125
|
|
43
126
|
def unrate_and_save(rater)
|
44
|
-
|
45
|
-
|
127
|
+
case rater
|
128
|
+
when Array
|
129
|
+
rater.each{|rater| unrate_and_save(mark, rater, weight)}
|
130
|
+
else
|
131
|
+
unrate(rater)
|
132
|
+
save
|
133
|
+
end
|
46
134
|
end
|
47
135
|
|
48
136
|
def rated?
|
@@ -50,7 +138,12 @@ module Mongoid
|
|
50
138
|
end
|
51
139
|
|
52
140
|
def rated_by?(rater)
|
53
|
-
|
141
|
+
case rater
|
142
|
+
when Array
|
143
|
+
rater.each{|rater| rated_by(mark, rater, weight)}
|
144
|
+
else
|
145
|
+
self.rating_marks.where(:rater_id => rater.id, :rater_class => rater.class.to_s).count == 1
|
146
|
+
end
|
54
147
|
end
|
55
148
|
|
56
149
|
def rating
|
@@ -87,9 +180,15 @@ module Mongoid
|
|
87
180
|
|
88
181
|
protected
|
89
182
|
|
183
|
+
def validate_rater!(rater)
|
184
|
+
unless self.class.valid_rater_class?(rater.class)
|
185
|
+
raise ArgumentError, "Not a valid rater: #{rater.class}, must be of one of #{self.class.rater_classes}"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
90
189
|
def validate_rating!(value)
|
91
|
-
if
|
92
|
-
raise ArgumentError, "Rating not in range #{
|
190
|
+
if !self.class.in_rating_range?(value)
|
191
|
+
raise ArgumentError, "Rating not in range #{self.class.rating_range}. Rating provided was #{value}."
|
93
192
|
end
|
94
193
|
end
|
95
194
|
|
data/mongoid_rateable.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "mongoid_rateable"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.3.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Peter Savichev (proton)"]
|
12
|
-
s.date = "2012-
|
12
|
+
s.date = "2012-11-03"
|
13
13
|
s.description = "Provides fields and methods for the rating manipulation on Mongoid documents."
|
14
14
|
s.email = "psavichev@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.files = [
|
21
21
|
".rspec",
|
22
22
|
".rvmrc",
|
23
|
+
"CHANGELOG.md",
|
23
24
|
"Gemfile",
|
24
25
|
"Gemfile.lock",
|
25
26
|
"LICENSE.txt",
|
@@ -51,7 +52,7 @@ Gem::Specification.new do |s|
|
|
51
52
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
52
53
|
s.add_runtime_dependency(%q<mongoid>, [">= 3.0"])
|
53
54
|
s.add_development_dependency(%q<bundler>, [">= 0"])
|
54
|
-
s.add_development_dependency(%q<jeweler>, ["
|
55
|
+
s.add_development_dependency(%q<jeweler>, [">= 1.6.2"])
|
55
56
|
s.add_development_dependency(%q<simplecov>, [">= 0.4.0"])
|
56
57
|
s.add_development_dependency(%q<rdoc>, [">= 0"])
|
57
58
|
s.add_development_dependency(%q<rspec>, [">= 2.0.0"])
|
@@ -59,7 +60,7 @@ Gem::Specification.new do |s|
|
|
59
60
|
else
|
60
61
|
s.add_dependency(%q<mongoid>, [">= 3.0"])
|
61
62
|
s.add_dependency(%q<bundler>, [">= 0"])
|
62
|
-
s.add_dependency(%q<jeweler>, ["
|
63
|
+
s.add_dependency(%q<jeweler>, [">= 1.6.2"])
|
63
64
|
s.add_dependency(%q<simplecov>, [">= 0.4.0"])
|
64
65
|
s.add_dependency(%q<rdoc>, [">= 0"])
|
65
66
|
s.add_dependency(%q<rspec>, [">= 2.0.0"])
|
@@ -68,7 +69,7 @@ Gem::Specification.new do |s|
|
|
68
69
|
else
|
69
70
|
s.add_dependency(%q<mongoid>, [">= 3.0"])
|
70
71
|
s.add_dependency(%q<bundler>, [">= 0"])
|
71
|
-
s.add_dependency(%q<jeweler>, ["
|
72
|
+
s.add_dependency(%q<jeweler>, [">= 1.6.2"])
|
72
73
|
s.add_dependency(%q<simplecov>, [">= 0.4.0"])
|
73
74
|
s.add_dependency(%q<rdoc>, [">= 0"])
|
74
75
|
s.add_dependency(%q<rspec>, [">= 2.0.0"])
|
data/spec/models/article.rb
CHANGED
data/spec/models/comment.rb
CHANGED
data/spec/rateable_spec.rb
CHANGED
@@ -57,11 +57,11 @@ describe Post do
|
|
57
57
|
@post.rates.should eql 5
|
58
58
|
end
|
59
59
|
|
60
|
-
it "should not raise exception if rate_value in
|
60
|
+
it "should not raise exception if rate_value in rating range" do
|
61
61
|
lambda { @article.rate 1, @sally }.should_not raise_error
|
62
62
|
end
|
63
63
|
|
64
|
-
it "should raise exception if rate_value not in
|
64
|
+
it "should raise exception if rate_value not in rating range" do
|
65
65
|
lambda { @article.rate 7, @sally }.should raise_error(ArgumentError)
|
66
66
|
end
|
67
67
|
|
@@ -510,11 +510,11 @@ describe Comment do
|
|
510
510
|
@comment1.rates.should eql 5
|
511
511
|
end
|
512
512
|
|
513
|
-
it "should not raise exception if rate_value in
|
513
|
+
it "should not raise exception if rate_value in rating range" do
|
514
514
|
lambda { @comment1.rate 1, @sally }.should_not raise_error
|
515
515
|
end
|
516
516
|
|
517
|
-
it "should raise exception if rate_value not in
|
517
|
+
it "should raise exception if rate_value not in rating range" do
|
518
518
|
lambda { @comment1.rate 9, @sally }.should raise_error(ArgumentError)
|
519
519
|
end
|
520
520
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid_rateable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-11-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: mongoid
|
@@ -48,7 +48,7 @@ dependencies:
|
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
49
49
|
none: false
|
50
50
|
requirements:
|
51
|
-
- -
|
51
|
+
- - ! '>='
|
52
52
|
- !ruby/object:Gem::Version
|
53
53
|
version: 1.6.2
|
54
54
|
type: :development
|
@@ -56,7 +56,7 @@ dependencies:
|
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
none: false
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ! '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 1.6.2
|
62
62
|
- !ruby/object:Gem::Dependency
|
@@ -134,6 +134,7 @@ extra_rdoc_files:
|
|
134
134
|
files:
|
135
135
|
- .rspec
|
136
136
|
- .rvmrc
|
137
|
+
- CHANGELOG.md
|
137
138
|
- Gemfile
|
138
139
|
- Gemfile.lock
|
139
140
|
- LICENSE.txt
|
@@ -167,7 +168,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
167
168
|
version: '0'
|
168
169
|
segments:
|
169
170
|
- 0
|
170
|
-
hash:
|
171
|
+
hash: 527634735
|
171
172
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
172
173
|
none: false
|
173
174
|
requirements:
|