voteable_mongo 0.8.1 → 0.9.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.rdoc CHANGED
@@ -1,3 +1,9 @@
1
+ == 0.9.0
2
+ * Add MongoMapper support
3
+ * Simplify voting algorithm
4
+ * vote / revote / unvote always return voteable object (votee)
5
+ * Tasks module bug fixes
6
+
1
7
  == 0.8.1
2
8
  * Fix gem release bug
3
9
 
data/README.rdoc CHANGED
@@ -1,6 +1,6 @@
1
1
  = Voteable Mongo
2
2
 
3
- voteable_mongo allows you to make your Mongoid::Document (mongo_mapper support coming soon) objects voteable (up or down) and tabulate votes count and votes point for you. For instance, in a forum, a user can vote up (or down) on a post or a comment.
3
+ voteable_mongo allows you to make your Mongoid::Document or MongoMapper::Document objects voteable (up or down) and tabulate votes count and votes point for you. For instance, in a forum, a user can vote up (or down) on a post or a comment.
4
4
 
5
5
  voteable_mongo is built for speed. It uses only one database request per collection to validate data, update data, and get updated data. Initial idea is based on http://cookbook.mongodb.org/patterns/votes
6
6
 
@@ -27,6 +27,7 @@ After that, remember to run "bundle install"
27
27
 
28
28
  === Make Post and Comment voteable, User become the voter
29
29
 
30
+ == Mongoid
30
31
  post.rb
31
32
 
32
33
  class Post
@@ -62,6 +63,42 @@ user.rb
62
63
  include Mongo::Voter
63
64
  end
64
65
 
66
+
67
+ == MongoMapper
68
+ post.rb
69
+
70
+ class Post
71
+ include MongoMapper::Document
72
+ include Mongo::Voteable
73
+
74
+ # set points for each vote
75
+ voteable self, :up => +1, :down => -1
76
+
77
+ many :comments
78
+ end
79
+
80
+ comment.rb
81
+
82
+ require 'post'
83
+
84
+ class Comment
85
+ include MongoMapper::Document
86
+ include Mongo::Voteable
87
+
88
+ belongs_to :post
89
+
90
+ voteable self, :up => +1, :down => -3
91
+ voteable Post, :up => +2, :down => -1
92
+ end
93
+
94
+ user.rb
95
+
96
+ class User
97
+ include MongoMapper::Document
98
+ include Mongo::Voter
99
+ end
100
+
101
+
65
102
  === Make a vote
66
103
 
67
104
  @user.vote(@post, :up)
@@ -89,9 +126,8 @@ Re-vote
89
126
 
90
127
  Un-vote
91
128
  Post.vote(:voter_id => user_id, :votee_id => post_id, :value => :up, :unvote => true)
92
-
93
- In-case you need updated voteable object, add :return_votee => true
94
- votee = Post.vote(:voter_id => user_id, :votee_id => post_id, :value => :up, :return_votee => true)
129
+
130
+ Note: vote function always return updated votee object
95
131
 
96
132
  === Get vote_value
97
133
 
data/Rakefile CHANGED
@@ -1,10 +1,10 @@
1
1
  require 'bundler'
2
2
  Bundler::GemHelper.install_tasks
3
3
 
4
- require "rspec"
5
- require "rspec/core/rake_task"
4
+ require 'rspec'
5
+ require 'rspec/core/rake_task'
6
6
  Rspec::Core::RakeTask.new(:spec) do |spec|
7
- spec.pattern = "spec/**/*_spec.rb"
7
+ spec.pattern = 'spec/**/*_spec.rb'
8
8
  end
9
9
 
10
- task :default => ["spec"]
10
+ task :default => ['spec']
data/TODO CHANGED
@@ -1,3 +1,8 @@
1
+ * Use mongo_ruby_driver as much as possible
2
+ * Move mongoid dependency to a separate module
3
+ * Learn from other gems how they manage and support multiple adaptors
4
+ - https://github.com/pluginaweek/state_machine/tree/master/lib/state_machine/integrations
5
+ - https://github.com/ianwhite/orm_adapter
1
6
  * Add support for mongo_mapper
2
7
  * Add options hash validations
3
8
  * Refactor specs
@@ -1,10 +1,9 @@
1
1
  require 'mongoid'
2
+
2
3
  require 'voteable_mongo/voteable'
3
4
  require 'voteable_mongo/voter'
5
+ require 'voteable_mongo/tasks'
4
6
 
5
- require 'voteable_mongo/voteable/tasks'
6
-
7
- # Add railtie
8
7
  if defined?(Rails)
9
8
  require 'voteable_mongo/railtie'
10
9
  end
@@ -0,0 +1,28 @@
1
+ module Mongo
2
+ module Voteable
3
+ module Integrations
4
+ module MongoMapper
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ key :votes, Hash, :default => DEFAULT_VOTES
9
+
10
+ class << self
11
+ alias_method :voteable_index, :ensure_index
12
+ alias_method :voteable_collection, :collection
13
+ end
14
+ end
15
+
16
+ module ClassMethods
17
+ def voteable_relation(class_name)
18
+ associations.find{ |x, r| r.class_name == class_name }.try(:last)
19
+ end
20
+
21
+ def voteable_foreign_key(metadata)
22
+ (metadata.options[:in] || "#{metadata.name}_id").to_s
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,31 @@
1
+ module Mongo
2
+ module Voteable
3
+ module Integrations
4
+ module Mongoid
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ field :votes, :type => Hash, :default => DEFAULT_VOTES
9
+
10
+ class << self
11
+ alias_method :voteable_index, :index
12
+ end
13
+ end
14
+
15
+ module ClassMethods
16
+ def voteable_relation(class_name)
17
+ relations.find{ |x, r| r.class_name == class_name }.try(:last)
18
+ end
19
+
20
+ def voteable_collection
21
+ collection.master.collection
22
+ end
23
+
24
+ def voteable_foreign_key(metadata)
25
+ metadata.foreign_key.to_s
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -10,7 +10,7 @@ module Mongo
10
10
  klass_voteable = voteable[class_name]
11
11
  puts "Init stats for #{class_name}" if log
12
12
  klass.collection.update({:votes => nil}, {
13
- '$set' => { :votes => Votes::DEFAULT_ATTRIBUTES }
13
+ '$set' => { :votes => DEFAULT_VOTES }
14
14
  }, {
15
15
  :safe => true,
16
16
  :multi => true
@@ -68,12 +68,6 @@ module Mongo
68
68
  'votes_count' => true,
69
69
  'votes_point' => true,
70
70
  'voteable' => true
71
- # 'votes.u' => true,
72
- # 'votes.d' => true,
73
- # 'votes.uc' => true,
74
- # 'votes.dc' => true,
75
- # 'votes.c' => true,
76
- # 'votes.p' => true
77
71
  }
78
72
  }, { :safe => true })
79
73
  end
@@ -95,12 +89,15 @@ module Mongo
95
89
  def self.remake_stats_for(doc, voteable)
96
90
  up_count = doc.up_voter_ids.length
97
91
  down_count = doc.down_voter_ids.length
98
-
99
92
  doc.update_attributes(
100
- 'votes.up_count' => up_count,
101
- 'votes.down_count' => down_count,
102
- 'votes.count' => up_count + down_count,
103
- 'votes.point' => voteable[:up].to_i*up_count + voteable[:down].to_i*down_count
93
+ 'votes' => {
94
+ 'up' => doc.up_voter_ids,
95
+ 'down' => doc.down_voter_ids,
96
+ 'up_count' => up_count,
97
+ 'down_count' => down_count,
98
+ 'count' => up_count + down_count,
99
+ 'point' => voteable[:up].to_i*up_count + voteable[:down].to_i*down_count
100
+ }
104
101
  )
105
102
  end
106
103
 
@@ -109,10 +106,10 @@ module Mongo
109
106
  VOTEABLE.each do |class_name, voteable|
110
107
  klass = class_name.constantize
111
108
  voteable.each do |parent_class_name, parent_voteable|
112
- relation_metadata = klass.relations[parent_class_name.underscore]
113
- if relation_metadata
109
+ metadata = klass.voteable_relation(parent_class_name)
110
+ if metadata
114
111
  parent_class = parent_class_name.constantize
115
- foreign_key = relation_metadata.foreign_key
112
+ foreign_key = klass.voteable_foreign_key(metadata)
116
113
  puts "Updating stats for #{class_name} > #{parent_class_name}" if log
117
114
  klass.all.each{ |doc|
118
115
  update_parent_stats_for(doc, parent_class, foreign_key, parent_voteable)
@@ -142,9 +139,11 @@ module Mongo
142
139
  'votes.down_count' => down_count
143
140
  )
144
141
  end
145
-
142
+
143
+ parent_ids = parent_id.is_a?(Array) ? parent_id : [ parent_id ]
144
+
146
145
  parent_class.collection.update(
147
- { '_id' => parent_id },
146
+ { '_id' => { '$in' => parent_ids } },
148
147
  { '$inc' => inc_options },
149
148
  { :safe => true }
150
149
  )
@@ -1,3 +1,3 @@
1
1
  module VoteableMongo
2
- VERSION = '0.8.1'
2
+ VERSION = '0.9.0'
3
3
  end
@@ -1,36 +1,45 @@
1
- require 'voteable_mongo/voteable/votes'
2
- require 'voteable_mongo/voteable/voting'
1
+ require 'voteable_mongo/voting'
2
+ require 'voteable_mongo/integrations/mongoid'
3
+ require 'voteable_mongo/integrations/mongo_mapper'
3
4
 
4
5
  module Mongo
5
6
  module Voteable
6
7
  extend ActiveSupport::Concern
7
8
 
9
+ DEFAULT_VOTES = {
10
+ 'up' => [],
11
+ 'down' => [],
12
+ 'up_count' => 0,
13
+ 'down_count' => 0,
14
+ 'count' => 0,
15
+ 'point' => 0
16
+ }
17
+
8
18
  included do
9
19
  include ::Mongo::Voteable::Voting
10
-
11
- field :votes, :type => Votes
12
20
 
13
- before_create do
14
- # Init votes so that counters and point have numeric values (0)
15
- self.votes = Votes::DEFAULT_ATTRIBUTES
21
+ if defined?(Mongoid) && defined?(field)
22
+ include ::Mongo::Voteable::Integrations::Mongoid
23
+ elsif defined?(MongoMapper)
24
+ include ::Mongo::Voteable::Integrations::MongoMapper
16
25
  end
17
26
 
18
27
  scope :voted_by, lambda { |voter|
19
- voter_id = voter.is_a?(BSON::ObjectId) ? voter : voter.id
20
- any_of({ 'votes.up' => voter_id }, { 'votes.down' => voter_id })
28
+ voter_id = voter.is_a?(::BSON::ObjectId) ? voter : voter.id
29
+ where('$or' => [{ 'votes.up' => voter_id }, { 'votes.down' => voter_id }])
21
30
  }
22
-
31
+
23
32
  scope :up_voted_by, lambda { |voter|
24
- voter_id = voter.is_a?(BSON::ObjectId) ? voter : voter.id
25
- where( 'votes.up' => voter_id )
33
+ voter_id = voter.is_a?(::BSON::ObjectId) ? voter : voter.id
34
+ where('votes.up' => voter_id)
26
35
  }
27
-
36
+
28
37
  scope :down_voted_by, lambda { |voter|
29
- voter_id = voter.is_a?(BSON::ObjectId) ? voter : voter.id
30
- where( 'votes.down' => voter_id )
38
+ voter_id = voter.is_a?(::BSON::ObjectId) ? voter : voter.id
39
+ where('votes.down' => voter_id)
31
40
  }
32
- end # include
33
-
41
+ end
42
+
34
43
  # How many points should be assigned for each up or down vote and other options
35
44
  # This hash should manipulated using voteable method
36
45
  VOTEABLE = {}
@@ -89,24 +98,21 @@ module Mongo
89
98
  validate_and_normalize_vote_options(options)
90
99
  down_voted_by(options[:voter_id]).where(:_id => options[:votee_id]).count == 1
91
100
  end
92
-
93
- private
101
+
94
102
  def create_voteable_indexes
95
- class_eval do
96
- # Compound index _id and voters.up, _id and voters.down
97
- # to make up_voted_by, down_voted_by, voted_by scopes and voting faster
98
- # Should run in background since it introduce new index value and
99
- # while waiting to build, the system can use _id for voting
100
- # http://www.mongodb.org/display/DOCS/Indexing+as+a+Background+Operation
101
- index [['votes.up', 1], ['_id', 1]], :unique => true
102
- index [['votes.down', 1], ['_id', 1]], :unique => true
103
-
104
- # Index counters and point for desc ordering
105
- index [['votes.up_count', -1]]
106
- index [['votes.down_count', -1]]
107
- index [['votes.count', -1]]
108
- index [['votes.point', -1]]
109
- end
103
+ # Compound index _id and voters.up, _id and voters.down
104
+ # to make up_voted_by, down_voted_by, voted_by scopes and voting faster
105
+ # Should run in background since it introduce new index value and
106
+ # while waiting to build, the system can use _id for voting
107
+ # http://www.mongodb.org/display/DOCS/Indexing+as+a+Background+Operation
108
+ voteable_index [['votes.up', 1], ['_id', 1]], :unique => true
109
+ voteable_index [['votes.down', 1], ['_id', 1]], :unique => true
110
+
111
+ # Index counters and point for desc ordering
112
+ voteable_index [['votes.up_count', -1]]
113
+ voteable_index [['votes.down_count', -1]]
114
+ voteable_index [['votes.count', -1]]
115
+ voteable_index [['votes.point', -1]]
110
116
  end
111
117
  end
112
118
 
@@ -3,8 +3,6 @@ module Mongo
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
- include ::Mongoid::Document
7
-
8
6
  scope :up_voted_for, lambda { |votee| where(:_id => { '$in' => votee.up_voter_ids }) }
9
7
  scope :down_voted_for, lambda { |votee| where(:_id => { '$in' => votee.down_voter_ids }) }
10
8
  scope :voted_for, lambda { |votee| where(:_id => { '$in' => votee.voter_ids }) }
@@ -41,7 +39,7 @@ module Mongo
41
39
  votee = unless options.is_a?(Hash)
42
40
  options
43
41
  else
44
- options[:votee] || options[:votee_type].classify.constantize.only(:votes).where(
42
+ options[:votee] || options[:votee_type].classify.constantize.where(
45
43
  :_id => options[:votee_id]
46
44
  ).first
47
45
  end
@@ -12,9 +12,8 @@ module Mongo
12
12
  # - :value: :up or :down
13
13
  # - :revote: if true change vote vote from :up to :down and vise versa
14
14
  # - :unvote: if true undo the voting
15
- # - :return_votee: if true always return updated voteable object
16
15
  #
17
- # @return [votes, false, nil]
16
+ # @return [votee, false]
18
17
  def vote(options)
19
18
  validate_and_normalize_vote_options(options)
20
19
  options[:voteable] = VOTEABLE[name][name]
@@ -28,27 +27,21 @@ module Mongo
28
27
  new_vote_query_and_update(options)
29
28
  end
30
29
 
31
- if options[:voteable][:update_parents] || options[:votee] || options[:return_votee]
32
- # If votee exits or need to update parent
33
- # use Collection#find_and_modify to retrieve updated votes data and parent_ids
34
- begin
35
- doc = collection.master.collection.find_and_modify(
36
- :query => query,
37
- :update => update,
38
- :new => true
39
- )
40
- # Update new votes data
41
- options[:votee].write_attribute('votes', doc['votes']) if options[:votee]
42
- update_parent_votes(doc, options) if options[:voteable][:update_parents]
43
- return options[:votee] || new(doc)
44
- rescue Exception => e
45
- # $stderr.puts "Mongo error: #{e.inspect}" # DEBUG
46
- # Don't update parents if operation fail or no matched object found
47
- return false
48
- end
30
+ # If votee exits or need to update parent
31
+ # use Collection#find_and_modify to retrieve updated votes data and parent_ids
32
+ doc = voteable_collection.find_and_modify(
33
+ :query => query,
34
+ :update => update,
35
+ :new => true
36
+ )
37
+
38
+ if doc
39
+ update_parent_votes(doc, options) if options[:voteable][:update_parents]
40
+ # Update new votes data
41
+ options[:votee].write_attribute('votes', doc['votes']) if options[:votee]
42
+ options[:votee] || new(doc)
49
43
  else
50
- # Just update and don't care the result
51
- collection.update(query, update)
44
+ false
52
45
  end
53
46
  end
54
47
  end
@@ -155,25 +148,15 @@ module Mongo
155
148
 
156
149
  def update_parent_votes(doc, options)
157
150
  VOTEABLE[name].each do |class_name, voteable|
158
- # For other class in VOTEABLE options, if has relationship with current class
159
- relation_metadata = relations.find{ |x, r| r.class_name == class_name }.try(:last)
160
- next unless relation_metadata.present?
161
-
162
- # If cannot find current votee foreign_key value for that class
163
- foreign_key_value = doc[relation_metadata.foreign_key.to_s]
164
- next unless foreign_key_value.present?
165
-
166
- if relation_metadata.relation == ::Mongoid::Relations::Referenced::In
167
- class_name.constantize.collection.update(
168
- { '_id' => foreign_key_value },
169
- { '$inc' => parent_inc_options(voteable, options) }
170
- )
171
- elsif relation_metadata.relation == ::Mongoid::Relations::Referenced::ManyToMany
172
- class_name.constantize.collection.update(
173
- { '_id' => { '$in' => foreign_key_value } },
174
- { '$inc' => parent_inc_options(voteable, options) },
175
- { :multi => true }
176
- )
151
+ if metadata = voteable_relation(class_name)
152
+ if parent_id = doc[voteable_foreign_key(metadata)]
153
+ parent_ids = parent_id.is_a?(Array) ? parent_id : [ parent_id ]
154
+ class_name.constantize.collection.update(
155
+ { '_id' => { '$in' => parent_ids } },
156
+ { '$inc' => parent_inc_options(voteable, options) },
157
+ { :multi => true }
158
+ )
159
+ end
177
160
  end
178
161
  end
179
162
  end
@@ -0,0 +1,11 @@
1
+ class Category
2
+ include MongoMapper::Document
3
+ include Mongo::Voteable
4
+
5
+ key :name, String
6
+
7
+ key :post_ids, Array
8
+ many :posts, :in => :post_ids
9
+
10
+ voteable self, :index => true
11
+ end
@@ -0,0 +1,13 @@
1
+ require File.join(File.dirname(__FILE__), 'post')
2
+
3
+ class Comment
4
+ include MongoMapper::Document
5
+ include Mongo::Voteable
6
+
7
+ key :content, String
8
+
9
+ belongs_to :post
10
+
11
+ voteable self, :up => +1, :down => -3
12
+ voteable Post, :up => +2, :down => -1
13
+ end
@@ -0,0 +1,17 @@
1
+ require File.join(File.dirname(__FILE__), 'category')
2
+
3
+ class Post
4
+ include MongoMapper::Document
5
+ include Mongo::Voteable
6
+
7
+ key :title, String
8
+ key :content, String
9
+
10
+ key :category_ids, Array
11
+ many :categories, :in => :category_ids
12
+
13
+ many :comments
14
+
15
+ voteable self, :up => +1, :down => -1, :index => true
16
+ voteable Category, :up => +3, :down => -5, :update_counters => false
17
+ end
@@ -0,0 +1,4 @@
1
+ class User
2
+ include MongoMapper::Document
3
+ include Mongo::Voter
4
+ end
File without changes
@@ -1,4 +1,4 @@
1
- require 'post'
1
+ require File.join(File.dirname(__FILE__), 'post')
2
2
 
3
3
  class Comment
4
4
  include Mongoid::Document
@@ -1,3 +1,5 @@
1
+ require File.join(File.dirname(__FILE__), 'category')
2
+
1
3
  class Post
2
4
  include Mongoid::Document
3
5
  include Mongo::Voteable
File without changes
data/spec/spec_helper.rb CHANGED
@@ -3,29 +3,35 @@ require 'bundler'
3
3
  Bundler.setup
4
4
 
5
5
 
6
+ if rand > 0.6
7
+ puts 'Mongoid'
8
+ require 'mongoid'
9
+ models_folder = File.join(File.dirname(__FILE__), 'mongoid/models')
10
+ Mongoid.configure do |config|
11
+ name = 'voteable_mongo_test'
12
+ host = 'localhost'
13
+ config.master = Mongo::Connection.new.db(name)
14
+ config.autocreate_indexes = true
15
+ end
16
+ else
17
+ puts 'MongoMapper'
18
+ require 'mongo_mapper'
19
+ models_folder = File.join(File.dirname(__FILE__), 'mongo_mapper/models')
20
+ MongoMapper.database = 'voteable_mongo_test'
21
+ end
22
+
23
+
6
24
  $LOAD_PATH.unshift(File.dirname(__FILE__))
7
25
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
8
26
 
9
- MODELS = File.join(File.dirname(__FILE__), "models")
10
- $LOAD_PATH.unshift(MODELS)
11
27
 
12
-
13
- require 'mongoid'
14
28
  require 'voteable_mongo'
15
29
  require 'rspec'
16
30
  require 'rspec/autorun'
17
31
 
18
-
19
- Mongoid.configure do |config|
20
- name = "voteable_mongo_test"
21
- host = "localhost"
22
- config.master = Mongo::Connection.new.db(name)
23
- end
24
-
25
-
26
- Dir[ File.join(MODELS, "*.rb") ].sort.each { |file| require File.basename(file) }
27
-
28
- User.collection.drop
29
- Post.collection.drop
30
- Comment.collection.drop
31
- Category.collection.drop
32
+ Dir[ File.join(models_folder, '*.rb') ].each { |file|
33
+ require file
34
+ file_name = File.basename(file).sub('.rb', '')
35
+ klass = file_name.classify.constantize
36
+ # klass.collection.drop
37
+ }
@@ -8,8 +8,8 @@ describe Mongo::Voteable::Tasks do
8
8
  end
9
9
 
10
10
  it 'after create votes has default value' do
11
- @post1.votes.should == Mongo::Voteable::Votes::DEFAULT_ATTRIBUTES
12
- @post2.votes.should == Mongo::Voteable::Votes::DEFAULT_ATTRIBUTES
11
+ @post1.votes.should == ::Mongo::Voteable::DEFAULT_VOTES
12
+ @post2.votes.should == ::Mongo::Voteable::DEFAULT_VOTES
13
13
  end
14
14
 
15
15
  it 'reset votes data' do
@@ -21,13 +21,14 @@ describe Mongo::Voteable::Tasks do
21
21
  end
22
22
 
23
23
  it 'init_stats recover votes default value' do
24
- Mongo::Voteable::Tasks.init_stats
24
+ ::Mongo::Voteable::Tasks.init_stats
25
+ ::Mongo::Voteable::Tasks.migrate_old_votes
25
26
 
26
27
  @post1.reload
27
28
  @post2.reload
28
-
29
- @post1.votes.should == Mongo::Voteable::Votes::DEFAULT_ATTRIBUTES
30
- @post2.votes.should == Mongo::Voteable::Votes::DEFAULT_ATTRIBUTES
29
+
30
+ @post1.votes.should == ::Mongo::Voteable::DEFAULT_VOTES
31
+ @post2.votes.should == ::Mongo::Voteable::DEFAULT_VOTES
31
32
  end
32
33
  end
33
34
  end
@@ -6,18 +6,20 @@ describe Mongo::Voteable do
6
6
  before do
7
7
  Post.collection.drop_indexes
8
8
  Category.collection.drop_indexes
9
+
10
+ Post.create_voteable_indexes
11
+ Category.create_voteable_indexes
9
12
  end
10
-
13
+
11
14
  it 'defines indexes' do
12
15
  [Post, Category].each do |klass|
13
- klass.create_indexes
14
16
  [ 'votes.up_1__id_1',
15
17
  'votes.down_1__id_1'
16
18
  ].each { |index_key|
17
19
  klass.collection.index_information.should have_key index_key
18
20
  klass.collection.index_information[index_key]['unique'].should be_true
19
21
  }
20
-
22
+
21
23
  [ 'votes.count_-1',
22
24
  'votes.up_count_-1',
23
25
  'votes.down_count_-1',
@@ -33,12 +35,9 @@ describe Mongo::Voteable do
33
35
  @category1 = Category.create!(:name => 'xyz')
34
36
  @category2 = Category.create!(:name => 'abc')
35
37
 
36
- @post1 = Post.create!
38
+ @post1 = Post.create!(:category_ids => [@category1.id, @category2.id])
37
39
  @post2 = Post.create!
38
-
39
- @post1.categories << @category1
40
- @category2.posts << @post1
41
-
40
+
42
41
  @comment = @post2.comments.create!
43
42
 
44
43
  @user1 = User.create!
@@ -123,7 +122,7 @@ describe Mongo::Voteable do
123
122
 
124
123
  context 'user1 vote up post1 the first time' do
125
124
  before :all do
126
- @post = @post1.vote(:voter_id => @user1.id, :value => :up, :return_votee => true)
125
+ @post = @post1.vote(:voter_id => @user1.id, :value => :up)
127
126
  end
128
127
 
129
128
  it 'validates return post' do
@@ -151,8 +150,8 @@ describe Mongo::Voteable do
151
150
  @post1.vote_value(@user2.id).should be_nil
152
151
  @post1.should_not be_voted_by(@user2.id)
153
152
 
154
- @post1.up_voters(User).should == [ @user1 ]
155
- @post1.voters(User).should == [ @user1 ]
153
+ @post1.up_voters(User).to_a.should == [ @user1 ]
154
+ @post1.voters(User).to_a.should == [ @user1 ]
156
155
  @post1.down_voters(User).should be_empty
157
156
 
158
157
  Post.voted_by(@user1).to_a.should == [ @post1 ]
@@ -206,9 +205,9 @@ describe Mongo::Voteable do
206
205
  end
207
206
 
208
207
  it 'post1 get voters' do
209
- @post1.up_voters(User).should == [ @user1 ]
210
- @post1.down_voters(User).should == [ @user2 ]
211
- @post1.voters(User).should == [ @user1, @user2 ]
208
+ @post1.up_voters(User).to_a.should == [ @user1 ]
209
+ @post1.down_voters(User).to_a.should == [ @user2 ]
210
+ @post1.voters(User).to_a.should == [ @user1, @user2 ]
212
211
  end
213
212
 
214
213
  it 'posts voted_by user1, user2 is post1 only' do
@@ -286,7 +285,9 @@ describe Mongo::Voteable do
286
285
  @post2.vote_value(@user1.id).should == :up
287
286
  @post2.vote_value(@user2.id).should be_nil
288
287
 
289
- Post.voted_by(@user1).sort.should == [ @post1, @post2 ].sort
288
+ Post.voted_by(@user1).size.should == 2
289
+ Post.voted_by(@user1).should be_include @post1
290
+ Post.voted_by(@user1).should be_include @post2
290
291
  end
291
292
  end
292
293
 
@@ -54,9 +54,9 @@ describe Mongo::Voter do
54
54
  Post.down_voted_by(@user1).to_a.should be_empty
55
55
  Post.voted_by(@user2).to_a.should be_empty
56
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 ]
57
+ User.up_voted_for(@post1).to_a.should == [ @user1 ]
58
+ User.down_voted_for(@post1).to_a.should be_empty
59
+ User.voted_for(@post1).to_a.should == [ @user1 ]
60
60
  end
61
61
 
62
62
  it 'user1 vote post1 has no effect' do
@@ -88,9 +88,9 @@ describe Mongo::Voter do
88
88
  Post.up_voted_by(@user2).to_a.should be_empty
89
89
  Post.down_voted_by(@user2).to_a.should == [ @post1 ]
90
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 ]
91
+ User.up_voted_for(@post1).to_a.should == [ @user1 ]
92
+ User.down_voted_for(@post1).to_a.should == [ @user2 ]
93
+ User.voted_for(@post1).to_a.should == [ @user1, @user2 ]
94
94
  end
95
95
  end
96
96
 
@@ -142,7 +142,9 @@ describe Mongo::Voter do
142
142
  @user1.vote_value(@post2).should == :up
143
143
  @user2.vote_value(@post2).should be_nil
144
144
 
145
- Post.voted_by(@user1).sort.should == [ @post1, @post2 ].sort
145
+ Post.voted_by(@user1).size.should == 2
146
+ Post.voted_by(@user1).should be_include @post1
147
+ Post.voted_by(@user1).should be_include @post2
146
148
  end
147
149
  end
148
150
  end
@@ -10,12 +10,12 @@ Gem::Specification.new do |s|
10
10
  s.email = ['alex@vinova.sg']
11
11
  s.homepage = 'https://github.com/vinova/voteable_mongo'
12
12
  s.summary = %q{Add Up / Down Voting for Mongoid and MongoMapper}
13
- s.description = %q{Up / Down Voting for Mongoid (MongoMapper support coming soon). Built for speed by using only one database request per collection to validate data, update data, and get updated data.}
13
+ s.description = %q{Built for speed by using only one database request per collection to validate, update, and retrieve updated data}
14
14
 
15
- s.add_development_dependency 'rspec'
15
+ s.add_development_dependency 'rspec', '~> 2.5.0'
16
16
  s.add_development_dependency 'mongoid', '~> 2.0.0'
17
- s.add_development_dependency 'mongo_mapper'
18
- s.add_development_dependency 'bson_ext'
17
+ s.add_development_dependency 'mongo_mapper', '~> 0.9.0'
18
+ s.add_development_dependency 'bson_ext', '~> 1.3.0'
19
19
 
20
20
  s.rubyforge_project = 'voteable_mongo'
21
21
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: voteable_mongo
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.8.1
5
+ version: 0.9.0
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-05-03 00:00:00 Z
13
+ date: 2011-05-04 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec
@@ -18,9 +18,9 @@ dependencies:
18
18
  requirement: &id001 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
- - - ">="
21
+ - - ~>
22
22
  - !ruby/object:Gem::Version
23
- version: "0"
23
+ version: 2.5.0
24
24
  type: :development
25
25
  version_requirements: *id001
26
26
  - !ruby/object:Gem::Dependency
@@ -40,9 +40,9 @@ dependencies:
40
40
  requirement: &id003 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
- - - ">="
43
+ - - ~>
44
44
  - !ruby/object:Gem::Version
45
- version: "0"
45
+ version: 0.9.0
46
46
  type: :development
47
47
  version_requirements: *id003
48
48
  - !ruby/object:Gem::Dependency
@@ -51,12 +51,12 @@ dependencies:
51
51
  requirement: &id004 !ruby/object:Gem::Requirement
52
52
  none: false
53
53
  requirements:
54
- - - ">="
54
+ - - ~>
55
55
  - !ruby/object:Gem::Version
56
- version: "0"
56
+ version: 1.3.0
57
57
  type: :development
58
58
  version_requirements: *id004
59
- description: Up / Down Voting for Mongoid (MongoMapper support coming soon). Built for speed by using only one database request per collection to validate data, update data, and get updated data.
59
+ description: Built for speed by using only one database request per collection to validate, update, and retrieve updated data
60
60
  email:
61
61
  - alex@vinova.sg
62
62
  executables: []
@@ -75,19 +75,24 @@ files:
75
75
  - Rakefile
76
76
  - TODO
77
77
  - lib/voteable_mongo.rb
78
+ - lib/voteable_mongo/integrations/mongo_mapper.rb
79
+ - lib/voteable_mongo/integrations/mongoid.rb
78
80
  - lib/voteable_mongo/railtie.rb
79
81
  - lib/voteable_mongo/railties/database.rake
82
+ - lib/voteable_mongo/tasks.rb
80
83
  - lib/voteable_mongo/version.rb
81
84
  - lib/voteable_mongo/voteable.rb
82
- - lib/voteable_mongo/voteable/tasks.rb
83
- - lib/voteable_mongo/voteable/votes.rb
84
- - lib/voteable_mongo/voteable/voting.rb
85
85
  - lib/voteable_mongo/voter.rb
86
+ - lib/voteable_mongo/voting.rb
86
87
  - spec/.rspec
87
- - spec/models/category.rb
88
- - spec/models/comment.rb
89
- - spec/models/post.rb
90
- - spec/models/user.rb
88
+ - spec/mongo_mapper/models/category.rb
89
+ - spec/mongo_mapper/models/comment.rb
90
+ - spec/mongo_mapper/models/post.rb
91
+ - spec/mongo_mapper/models/user.rb
92
+ - spec/mongoid/models/category.rb
93
+ - spec/mongoid/models/comment.rb
94
+ - spec/mongoid/models/post.rb
95
+ - spec/mongoid/models/user.rb
91
96
  - spec/spec_helper.rb
92
97
  - spec/voteable_mongo/tasks_spec.rb
93
98
  - spec/voteable_mongo/voteable_spec.rb
@@ -121,10 +126,14 @@ signing_key:
121
126
  specification_version: 3
122
127
  summary: Add Up / Down Voting for Mongoid and MongoMapper
123
128
  test_files:
124
- - spec/models/category.rb
125
- - spec/models/comment.rb
126
- - spec/models/post.rb
127
- - spec/models/user.rb
129
+ - spec/mongo_mapper/models/category.rb
130
+ - spec/mongo_mapper/models/comment.rb
131
+ - spec/mongo_mapper/models/post.rb
132
+ - spec/mongo_mapper/models/user.rb
133
+ - spec/mongoid/models/category.rb
134
+ - spec/mongoid/models/comment.rb
135
+ - spec/mongoid/models/post.rb
136
+ - spec/mongoid/models/user.rb
128
137
  - spec/spec_helper.rb
129
138
  - spec/voteable_mongo/tasks_spec.rb
130
139
  - spec/voteable_mongo/voteable_spec.rb
@@ -1,19 +0,0 @@
1
- module Mongo
2
- module Voteable
3
-
4
- class Votes
5
- include Mongoid::Document
6
-
7
- field :up, :type => Array, :default => []
8
- field :down, :type => Array, :default => []
9
- field :up_count, :type => Integer, :default => 0
10
- field :down_count, :type => Integer, :default => 0
11
- field :count, :type => Integer, :default => 0
12
- field :point, :type => Integer, :default => 0
13
-
14
- DEFAULT_ATTRIBUTES = new.attributes
15
- DEFAULT_ATTRIBUTES.delete('_id')
16
- end
17
-
18
- end
19
- end