voteable_mongoid 0.7.3 → 0.7.4

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.
@@ -1,3 +1,10 @@
1
+ == 0.7.4
2
+ * Add Voteable#up_voters(VoterClass), Voteable#down_voters(VoterClass), Voteable#voters(VoterClass)
3
+ * Add Voter scopes: Voter.up_voted_for(voteable_object), Voter.down_voted_for(voteable_object), Voter.voted_for(voteable_object)
4
+ * Add voteable ..., :index => true options
5
+ * Optimization on unvote and revote validations
6
+ * Fix for :up & :down points are nil in rake tasks
7
+
1
8
  == 0.7.3
2
9
  * Add :return_votee => true option to vote function to warranty always return voteable object
3
10
  * Add Voteable.voted?, Voteable.up_voted?, Voteable.down_voted?
@@ -1,3 +1,3 @@
1
1
  module VoteableMongoid
2
- VERSION = '0.7.3'
2
+ VERSION = '0.7.4'
3
3
  end
@@ -46,8 +46,12 @@ module Mongoid
46
46
  def voteable(klass = self, options = nil)
47
47
  VOTEABLE[name] ||= {}
48
48
  VOTEABLE[name][klass.name] ||= options
49
- if klass != self
50
- VOTEABLE[name][name][:update_parents] = true
49
+ if klass == self
50
+ if options[:index] == true
51
+ create_voteable_indexes
52
+ end
53
+ else
54
+ VOTEABLE[name][name][:update_parents] ||= true
51
55
  end
52
56
  end
53
57
 
@@ -86,6 +90,25 @@ module Mongoid
86
90
  validate_and_normalize_vote_options(options)
87
91
  down_voted_by(options[:voter_id]).where(:_id => options[:votee_id]).count == 1
88
92
  end
93
+
94
+ private
95
+ def create_voteable_indexes
96
+ class_eval do
97
+ # Compound index _id and voters.up, _id and voters.down
98
+ # to make up_voted_by, down_voted_by, voted_by scopes and voting faster
99
+ # Should run in background since it introduce new index value and
100
+ # while waiting to build, the system can use _id for voting
101
+ # http://www.mongodb.org/display/DOCS/Indexing+as+a+Background+Operation
102
+ index [['votes.up', 1], ['_id', 1]], :unique => true, :background => true
103
+ index [['votes.down', 1], ['_id', 1]], :unique => true, :background => true
104
+
105
+ # Index counters and point for desc ordering
106
+ index [['votes.count', -1]]
107
+ index [['votes.up_count', -1]]
108
+ index [['votes.down_count', -1]]
109
+ index [['votes.point', -1]]
110
+ end
111
+ end
89
112
  end
90
113
 
91
114
  module InstanceMethods
@@ -133,6 +156,11 @@ module Mongoid
133
156
  votes.try(:[], 'down') || []
134
157
  end
135
158
 
159
+ # Array of voter ids
160
+ def voter_ids
161
+ up_voter_ids + down_voter_ids
162
+ end
163
+
136
164
  # Get the number of up votes
137
165
  def up_votes_count
138
166
  votes.try(:[], 'up_count') || 0
@@ -152,7 +180,21 @@ module Mongoid
152
180
  def votes_point
153
181
  votes.try(:[], 'point') || 0
154
182
  end
183
+
184
+ # Get up voters
185
+ def up_voters(klass)
186
+ klass.where(:_id => { '$in' => up_voter_ids })
187
+ end
188
+
189
+ # Get down voters
190
+ def down_voters(klass)
191
+ klass.where(:_id => { '$in' => down_voter_ids })
192
+ end
193
+
194
+ # Get voters
195
+ def voters(klass)
196
+ klass.where(:_id => { '$in' => voter_ids })
197
+ end
155
198
  end
156
-
157
199
  end
158
200
  end
@@ -59,7 +59,7 @@ module Mongoid
59
59
  'up_count' => up_count,
60
60
  'down_count' => down_count,
61
61
  'count' => up_count + down_count,
62
- 'point' => voteable[:up]*up_count + voteable[:down]*down_count
62
+ 'point' => voteable[:up].to_i*up_count + voteable[:down].to_i*down_count
63
63
  }
64
64
  },
65
65
  '$unset' => {
@@ -94,7 +94,7 @@ module Mongoid
94
94
  'votes.up_count' => up_count,
95
95
  'votes.down_count' => down_count,
96
96
  'votes.count' => up_count + down_count,
97
- 'votes.point' => voteable[:up]*up_count + voteable[:down]*down_count
97
+ 'votes.point' => voteable[:up].to_i*up_count + voteable[:down].to_i*down_count
98
98
  )
99
99
  end
100
100
 
@@ -126,7 +126,7 @@ module Mongoid
126
126
  return if up_count == 0 && down_count == 0
127
127
 
128
128
  inc_options = {
129
- 'votes.point' => voteable[:up]*up_count + voteable[:down]*down_count
129
+ 'votes.point' => voteable[:up].to_i*up_count + voteable[:down].to_i*down_count
130
130
  }
131
131
 
132
132
  unless voteable[:update_counters] == false
@@ -78,10 +78,11 @@ module Mongoid
78
78
  }, {
79
79
  # then update
80
80
  '$push' => { positive_voter_ids => options[:voter_id] },
81
- '$inc' => {
81
+ '$inc' => {
82
82
  'votes.count' => +1,
83
83
  positive_votes_count => +1,
84
- 'votes.point' => options[:voteable][options[:value]] }
84
+ 'votes.point' => options[:voteable][options[:value]]
85
+ }
85
86
  }
86
87
  end
87
88
 
@@ -104,7 +105,9 @@ module Mongoid
104
105
  return {
105
106
  # Validate voter_id did a vote with value for votee_id
106
107
  :_id => options[:votee_id],
107
- positive_voter_ids => { '$ne' => options[:voter_id] },
108
+ # Can skip $ne validation since creating a new vote
109
+ # already warranty that a voter can vote one only
110
+ # positive_voter_ids => { '$ne' => options[:voter_id] },
108
111
  negative_voter_ids => options[:voter_id]
109
112
  }, {
110
113
  # then update
@@ -133,7 +136,9 @@ module Mongoid
133
136
  return {
134
137
  :_id => options[:votee_id],
135
138
  # Validate if voter_id did a vote with value for votee_id
136
- negative_voter_ids => { '$ne' => options[:voter_id] },
139
+ # Can skip $ne validation since creating a new vote
140
+ # already warranty that a voter can vote one only
141
+ # negative_voter_ids => { '$ne' => options[:voter_id] },
137
142
  positive_voter_ids => options[:voter_id]
138
143
  }, {
139
144
  # then update
@@ -1,7 +1,15 @@
1
1
  module Mongoid
2
2
  module Voter
3
3
  extend ActiveSupport::Concern
4
-
4
+
5
+ included do
6
+ include ::Mongoid::Document
7
+
8
+ scope :up_voted_for, lambda { |votee| where(:_id => { '$in' => votee.up_voter_ids }) }
9
+ scope :down_voted_for, lambda { |votee| where(:_id => { '$in' => votee.down_voter_ids }) }
10
+ scope :voted_for, lambda { |votee| where(:_id => { '$in' => votee.voter_ids }) }
11
+ end
12
+
5
13
  module InstanceMethods
6
14
  # Check to see if this voter voted on the votee or not
7
15
  #
@@ -5,4 +5,6 @@ class Category
5
5
  field :name
6
6
 
7
7
  has_and_belongs_to_many :posts
8
+
9
+ voteable self, :index => true
8
10
  end
@@ -8,6 +8,6 @@ class Post
8
8
  has_and_belongs_to_many :categories
9
9
  has_many :comments
10
10
 
11
- voteable self, :up => +1, :down => -1
11
+ voteable self, :up => +1, :down => -1, :index => true
12
12
  voteable Category, :up => +3, :down => -5, :update_counters => false
13
13
  end
@@ -1,6 +1,35 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
3
  describe Mongoid::Voteable do
4
+
5
+ context 'when :index is passed as an argument' do
6
+ before do
7
+ Post.collection.drop_indexes
8
+ Category.collection.drop_indexes
9
+ end
10
+
11
+ it 'defines indexes' do
12
+ [Post, Category].each do |klass|
13
+ klass.create_indexes
14
+ [ 'votes.up_1__id_1',
15
+ 'votes.down_1__id_1'
16
+ ].each { |index_key|
17
+ klass.collection.index_information.should have_key index_key
18
+ klass.collection.index_information[index_key]['unique'].should be_true
19
+ klass.collection.index_information[index_key]['background'].should be_true
20
+ }
21
+
22
+ [ 'votes.count_-1',
23
+ 'votes.up_count_-1',
24
+ 'votes.down_count_-1',
25
+ 'votes.point_-1'
26
+ ].each { |index_key|
27
+ klass.collection.index_information.should have_key index_key
28
+ }
29
+ end
30
+ end
31
+ end
32
+
4
33
  before :all do
5
34
  @category1 = Category.create!(:name => 'xyz')
6
35
  @category2 = Category.create!(:name => 'abc')
@@ -123,6 +152,10 @@ describe Mongoid::Voteable do
123
152
  @post1.vote_value(@user2.id).should be_nil
124
153
  @post1.should_not be_voted_by(@user2.id)
125
154
 
155
+ @post1.up_voters(User).should == [ @user1 ]
156
+ @post1.voters(User).should == [ @user1 ]
157
+ @post1.down_voters(User).should be_empty
158
+
126
159
  Post.voted_by(@user1).to_a.should == [ @post1 ]
127
160
  Post.voted_by(@user2).to_a.should be_empty
128
161
 
@@ -173,6 +206,12 @@ describe Mongoid::Voteable do
173
206
  @post1.vote_value(@user2.id).should == :down
174
207
  end
175
208
 
209
+ it 'post1 get voters' do
210
+ @post1.up_voters(User).should == [ @user1 ]
211
+ @post1.down_voters(User).should == [ @user2 ]
212
+ @post1.voters(User).should == [ @user1, @user2 ]
213
+ end
214
+
176
215
  it 'posts voted_by user1, user2 is post1 only' do
177
216
  Post.voted_by(@user1).to_a.should == [ @post1 ]
178
217
  Post.voted_by(@user2).to_a.should == [ @post1 ]
@@ -248,7 +287,7 @@ describe Mongoid::Voteable do
248
287
  @post2.vote_value(@user1.id).should == :up
249
288
  @post2.vote_value(@user2.id).should be_nil
250
289
 
251
- Post.voted_by(@user1).to_a.should == [ @post1, @post2 ]
290
+ Post.voted_by(@user1).sort.should == [ @post1, @post2 ].sort
252
291
  end
253
292
  end
254
293
 
@@ -53,6 +53,10 @@ describe Mongoid::Voter do
53
53
  Post.up_voted_by(@user1).to_a.should == [ @post1 ]
54
54
  Post.down_voted_by(@user1).to_a.should be_empty
55
55
  Post.voted_by(@user2).to_a.should be_empty
56
+
57
+ User.up_voted_for(@post1).should == [ @user1 ]
58
+ User.down_voted_for(@post1).should be_empty
59
+ User.voted_for(@post1).should == [ @user1 ]
56
60
  end
57
61
 
58
62
  it 'user1 vote post1 has no effect' do
@@ -83,6 +87,10 @@ describe Mongoid::Voter do
83
87
  Post.voted_by(@user2).to_a.should == [ @post1 ]
84
88
  Post.up_voted_by(@user2).to_a.should be_empty
85
89
  Post.down_voted_by(@user2).to_a.should == [ @post1 ]
90
+
91
+ User.up_voted_for(@post1).should == [ @user1 ]
92
+ User.down_voted_for(@post1).should == [ @user2 ]
93
+ User.voted_for(@post1).should == [ @user1, @user2 ]
86
94
  end
87
95
  end
88
96
 
@@ -134,7 +142,7 @@ describe Mongoid::Voter do
134
142
  @user1.vote_value(@post2).should == :up
135
143
  @user2.vote_value(@post2).should be_nil
136
144
 
137
- Post.voted_by(@user1).to_a.should == [ @post1, @post2 ]
145
+ Post.voted_by(@user1).sort.should == [ @post1, @post2 ].sort
138
146
  end
139
147
  end
140
148
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: voteable_mongoid
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.7.3
5
+ version: 0.7.4
6
6
  platform: ruby
7
7
  authors:
8
8
  - Alex Nguyen
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-04-24 00:00:00 Z
13
+ date: 2011-05-02 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: mongoid