mongoid_rateable 0.2.3 → 0.3.0
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.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:
|