mongoid_atomic_votes 0.1.0 → 0.1.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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/mongoid_atomic_votes/atomic_votes.rb +68 -32
- data/lib/mongoid_atomic_votes/version.rb +1 -1
- data/lib/mongoid_atomic_votes/vote.rb +1 -1
- data/spec/atomic_votes_spec.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c011039cca7f56e8f6da3de59f97510592784434
|
4
|
+
data.tar.gz: 6724540bc0728cc2da34b6b450f0ee3fa8e91653
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27e37c374f7b11244dae7a7e77bcc1700204db22ac6257d6831f5a296c9ceb82381b3605af14f689effa3b19e90f8e14d29627b5f7a9fc882d3ecac5e2499027
|
7
|
+
data.tar.gz: 11d7461bfec82ae8d1b19a76dff29cc5c54660f24ca793999b0d0ee955a87e9c092aa22824cdb6409b8afeef2aefe277907adc44547fe046b165e42eb2975879
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# MongoidAtomicVotes
|
2
2
|
|
3
|
-
[](https://travis-ci.org/hck/mongoid_atomic_votes)
|
3
|
+
[](https://travis-ci.org/hck/mongoid_atomic_votes) [](https://codeclimate.com/github/hck/mongoid_atomic_votes)
|
4
4
|
|
5
5
|
mongoid_atomic_votes adds possibility to vote on mongoid documents.
|
6
6
|
Each vote mark goes to db by one atomic query that increments vote count, sets vote_value (overall document vote score) and pulls vote mark (embedded document with additional info about voter) to db.
|
@@ -1,48 +1,42 @@
|
|
1
1
|
module Mongoid
|
2
2
|
module AtomicVotes
|
3
|
-
|
4
|
-
base
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
class << self
|
4
|
+
def included(base)
|
5
|
+
define_relations(base)
|
6
|
+
define_scopes(base)
|
7
|
+
base.extend ClassMethods
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
private
|
11
|
+
def define_relations(base)
|
12
|
+
base.field :vote_count, type: Integer, default: 0
|
13
|
+
base.field :vote_value, type: Float, default: nil
|
14
|
+
base.embeds_many :votes, class_name: 'Mongoid::AtomicVotes::Vote', as: :atomic_voteable
|
15
|
+
end
|
14
16
|
|
15
|
-
base
|
17
|
+
def define_scopes(base)
|
18
|
+
base.scope :not_voted, base.where(:vote_value.exists => false)
|
19
|
+
base.scope :voted, base.where(:vote_value.exists => true)
|
20
|
+
base.scope :voted_by, ->(resource) do
|
21
|
+
base.where('votes.voted_by_id' => resource.id, 'votes.voter_type' => resource.class.name)
|
22
|
+
end
|
23
|
+
base.scope :vote_value_in, ->(range) do
|
24
|
+
base.where(:vote_value.gte => range.begin, :vote_value.lte => range.end)
|
25
|
+
end
|
26
|
+
base.scope :highest_voted, ->(limit=10) { base.order_by(:vote_value.desc).limit(limit) }
|
27
|
+
end
|
16
28
|
end
|
17
29
|
|
18
30
|
def vote(value, voted_by)
|
19
31
|
mark = Vote.new(value: value, voted_by_id: voted_by.id, voter_type: voted_by.class.name)
|
20
32
|
return false unless mark.valid?
|
21
|
-
|
22
|
-
_assigning do
|
23
|
-
self.votes << mark
|
24
|
-
self.vote_value = (self.vote_count * (self.vote_value || 0) + value).to_f / (self.vote_count + 1)
|
25
|
-
self.vote_count += 1
|
26
|
-
end
|
27
|
-
|
28
|
-
self.collection.
|
29
|
-
find({_id: self.id}).
|
30
|
-
update('$inc' => {vote_count: 1}, '$set' => {vote_value: self.vote_value}, '$push' => {votes: mark.as_json}).nil?
|
33
|
+
add_vote_mark(mark)
|
31
34
|
end
|
32
35
|
|
33
36
|
def retract(voted_by)
|
34
37
|
mark = self.votes.find_by(voted_by_id: voted_by.id)
|
35
38
|
return false unless mark
|
36
|
-
|
37
|
-
_assigning do
|
38
|
-
self.votes.reject!{|v| v.id == mark.id}
|
39
|
-
self.vote_value = self.vote_count == 1 ? 0 : (self.vote_value * self.vote_count - mark.value) / (self.vote_count - 1)
|
40
|
-
self.vote_count -= 1
|
41
|
-
end
|
42
|
-
|
43
|
-
self.collection.
|
44
|
-
find({_id: self.id}).
|
45
|
-
update('$inc' => {vote_count: -1}, '$set' => {vote_value: vote_value}, '$pull' => {votes: {_id: mark.id}}).nil?
|
39
|
+
remove_vote_mark(mark)
|
46
40
|
end
|
47
41
|
|
48
42
|
def has_votes?
|
@@ -61,5 +55,47 @@ module Mongoid
|
|
61
55
|
Vote.send(__method__, val)
|
62
56
|
end
|
63
57
|
end
|
58
|
+
|
59
|
+
private
|
60
|
+
def update_votes(mark, retract=false)
|
61
|
+
opts = {
|
62
|
+
'$inc' => {vote_count: retract ? -1 : 1},
|
63
|
+
'$set' => {vote_value: self.vote_value}
|
64
|
+
}
|
65
|
+
|
66
|
+
if retract
|
67
|
+
opts['$pull'] = {votes: {_id: mark.id}}
|
68
|
+
else
|
69
|
+
opts['$push'] = {votes: mark.as_json}
|
70
|
+
end
|
71
|
+
|
72
|
+
self.collection.find(_id: self.id).update(opts).nil?
|
73
|
+
end
|
74
|
+
|
75
|
+
def update_vote_value(mark, retract=false)
|
76
|
+
value, vote_count_diff = [mark.value, 1].map{|v| v * (retract ? -1 : 1)}
|
77
|
+
self.vote_value = if self.vote_count == 1 && retract
|
78
|
+
nil
|
79
|
+
else
|
80
|
+
(self.vote_count * self.vote_value.to_f + value) / (self.vote_count + vote_count_diff)
|
81
|
+
end
|
82
|
+
self.vote_count += vote_count_diff
|
83
|
+
end
|
84
|
+
|
85
|
+
def add_vote_mark(mark)
|
86
|
+
_assigning do
|
87
|
+
self.votes << mark
|
88
|
+
update_vote_value(mark)
|
89
|
+
end
|
90
|
+
update_votes(mark)
|
91
|
+
end
|
92
|
+
|
93
|
+
def remove_vote_mark(mark)
|
94
|
+
_assigning do
|
95
|
+
self.votes.reject!{|v| v.id == mark.id}
|
96
|
+
update_vote_value(mark, true)
|
97
|
+
end
|
98
|
+
update_votes(mark, true)
|
99
|
+
end
|
64
100
|
end
|
65
|
-
end
|
101
|
+
end
|
data/spec/atomic_votes_spec.rb
CHANGED
@@ -128,7 +128,7 @@ describe Post do
|
|
128
128
|
@post.retract(u).should be_true
|
129
129
|
cnt -= 1
|
130
130
|
|
131
|
-
vote_value = @post.votes.size == 0 ?
|
131
|
+
vote_value = @post.votes.size == 0 ? nil : @post.votes.map(&:value).sum.to_f/@post.votes.size
|
132
132
|
|
133
133
|
@post.vote_value.should == vote_value
|
134
134
|
@post.vote_count.should == @post.votes.size
|
@@ -157,4 +157,4 @@ describe Post do
|
|
157
157
|
@vote.errors.messages[:value].first.should =~ /included in the list/
|
158
158
|
end
|
159
159
|
end
|
160
|
-
end
|
160
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid_atomic_votes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hck
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-10-
|
11
|
+
date: 2013-10-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mongoid
|