mongoid_atomic_votes 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![Build Status](https://travis-ci.org/hck/mongoid_atomic_votes.png)](https://travis-ci.org/hck/mongoid_atomic_votes)
|
3
|
+
[![Build Status](https://travis-ci.org/hck/mongoid_atomic_votes.png)](https://travis-ci.org/hck/mongoid_atomic_votes) [![Code Climate](https://codeclimate.com/github/hck/mongoid_atomic_votes.png)](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
|