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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dab2d4f9b64027bc3f6b295dfc2e4ae393c92e55
4
- data.tar.gz: 0e193882d6d60226fbb6c73e0eec82acb1d75248
3
+ metadata.gz: c011039cca7f56e8f6da3de59f97510592784434
4
+ data.tar.gz: 6724540bc0728cc2da34b6b450f0ee3fa8e91653
5
5
  SHA512:
6
- metadata.gz: 59babe4137d182f0f7d2956646423ae0ca473c076fc592ecbe8001fd0b998b491423359c1fceb93083a3956d18a780bb415f4ba84728edea614acc7e6271d559
7
- data.tar.gz: 875c55107133aa43fcfd71f211193c6fa8f3fc41e3cc638d63d41657ca1f148c09d307bc97045d6af2b2b4740ffbd62c515d6daccaae62b941a93c7298f5043a
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
- def self.included(base)
4
- base.field :vote_count, type: Integer, default: 0
5
- base.field :vote_value, type: Float, default: nil
6
-
7
- base.embeds_many :votes, class_name: 'Mongoid::AtomicVotes::Vote', as: :atomic_voteable
3
+ class << self
4
+ def included(base)
5
+ define_relations(base)
6
+ define_scopes(base)
7
+ base.extend ClassMethods
8
+ end
8
9
 
9
- base.scope :not_voted, base.where(:vote_value.exists => false)
10
- base.scope :voted, base.where(:vote_value.exists => true)
11
- base.scope :voted_by, ->(resource) { base.where('votes.voted_by_id' => resource.id, 'votes.voter_type' => resource.class.name) }
12
- base.scope :vote_value_in, ->(range) { base.where(:vote_value.gte => range.begin, :vote_value.lte => range.end) }
13
- base.scope :highest_voted, ->(limit=10) { base.order_by(:vote_value.desc).limit(limit) }
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.extend ClassMethods
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
@@ -1,5 +1,5 @@
1
1
  module Mongoid
2
2
  module AtomicVotes
3
- VERSION = "0.1.0"
3
+ VERSION = "0.1.1"
4
4
  end
5
5
  end
@@ -24,4 +24,4 @@ class Mongoid::AtomicVotes::Vote
24
24
  @@vote_range
25
25
  end
26
26
  end
27
- end
27
+ end
@@ -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 ? 0 : @post.votes.map(&:value).sum.to_f/@post.votes.size
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.0
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-21 00:00:00.000000000 Z
11
+ date: 2013-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mongoid