voteable_mongo 0.9.2 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,6 @@
1
+ == 0.9.3
2
+ * Support mongoid ~> 2.0, mongo_mapper ~> 0.9
3
+
1
4
  == 0.9.2
2
5
  * Replace votee_type to votee_class
3
6
  * Bug fixes
@@ -2,34 +2,37 @@
2
2
 
3
3
  voteable_mongo allows you to make your Mongoid::Document or MongoMapper::Document objects voteable 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. It's optimized for speed by using only ONE database request per collection to validate, update, and retrieve updated data.
4
4
 
5
- Initial idea based on http://cookbook.mongodb.org/patterns/votes
5
+ Initial idea based on http://cookbook.mongodb.org/patterns/votes.
6
6
 
7
- Sample app at https://github.com/vinova/simple_qa
7
+ Sample app at https://github.com/vinova/simple_qa.
8
8
 
9
9
  Wonder how fast voteable_mongo is compare to other SQL & MongoDB solutions?
10
10
  Visit benchmarks at https://github.com/vinova/voteable_benchmarks
11
11
 
12
12
  == Why voteable_mongo?
13
13
 
14
- There are various solution for up / down voting problem (see list below)
15
- * https://github.com/medihack/make_voteable
16
- * https://github.com/brady8/thumbs_up
17
- * https://github.com/icaruswings/mm-voteable
18
- * https://github.com/jcoene/mongoid_voteable
14
+ There are various solutions for up / down voting problem (1[https://github.com/medihack/make_voteable], 2[https://github.com/brady8/thumbs_up], 3[https://github.com/icaruswings/mm-voteable], 4[https://github.com/jcoene/mongoid_voteable], ...). Most of them using additional votes table (SQL) or votes collection (MongoDB) to store votes and do data tabulation on that votes table or votes collection.
19
15
 
20
- Most of them using additional votes table (SQL) or votes collection (MongoDB) to store votes and do data tabulation on that votes table or votes collection.
16
+ voteable_mongo is different. It takes advantage of document-oriented database to store all related votes data inside voteable document. That has following benefits:
21
17
 
22
- voteable_mongo is different. It can do much more with a single request to MongoDB database. It takes advantage of document-oriented database to store all related votes data inside voteable document do you don't have to maintain additional collection. When do vote up, vote down, revote, unvote, voteable_mongo validates vote data, updates voteable document data and retrieves updated data using only ONE database request (thanks to atomic find_and_modify operation). When voteable document is loaded, all votes data related to it also be loaded, no more additional database requests to see how many votes this document got?, who give up votes? who give down vote? total vote points, votes count ...
18
+ * Don't have to maintain additional votes table or votes collection.
23
19
 
24
- So use voteable_mongo and save your database requests for other other tasks.
20
+ * When voteable document is loaded, all votes data related to it also be loaded, no more additional database requests to see how many votes this document got, who give up votes who give down vote, total vote points, votes count ...
21
+
22
+ * When vote up, vote down, revote, unvote, voteable_mongo validates vote data, updates voteable document and retrieves updated data using only ONE database request thanks to atomic findAndModify operation.
23
+
24
+ * Atomic operations on single document warranty data integrity that makes sure if votes created / changed / deleted their associated counters and points will be updated.
25
+
26
+ So use voteable_mongo for less maintain cost, data integrity and save database requests for other tasks.
25
27
 
26
28
  == Sites using voteable_mongo
29
+ * http://www.naiku.net
27
30
  * http://www.amorveneris.com
28
- * http://zheye.org (https://github.com/huacnlee/quora)
31
+ * http://zheye.org
29
32
 
30
33
  == Installation
31
34
 
32
- === Rails 3.0.x
35
+ === Rails 3.x
33
36
 
34
37
  To install the gem, add this to your Gemfile
35
38
 
@@ -183,18 +186,18 @@ Note: vote function always return updated votee object
183
186
 
184
187
  == Utilities
185
188
 
186
- === Re-generate counters and vote points in case you change :up / :down vote points
187
- Rails
188
- rake mongo:voteable:remake_stats
189
- Ruby
190
- Mongo::Voteable::Tasks.remake_stats
191
-
192
189
  === Set counters and point to 0 for uninitialized voteable objects in order sort and query
193
190
  Rails
194
191
  rake mongo:voteable:init_stats
195
192
  Ruby
196
193
  Mongo::Voteable::Tasks::init_stats
197
194
 
195
+ === Re-generate counters and vote points in case you change :up / :down vote points
196
+ Rails
197
+ rake mongo:voteable:remake_stats
198
+ Ruby
199
+ Mongo::Voteable::Tasks.remake_stats
200
+
198
201
  === Migrate from voteable_mongoid version < 0.7.0
199
202
  Rails
200
203
  rake mongo:voteable:migrate_old_votes
@@ -203,7 +206,7 @@ Ruby
203
206
 
204
207
  == Credits
205
208
  * Alex Nguyen - Author
206
- * https://github.com/vinova/voteable_mongo/contributors
209
+ * Contributors[https://github.com/vinova/voteable_mongo/contributors]
207
210
 
208
211
  Copyright (c) 2010-2011 Vinova Pte Ltd
209
212
 
data/Rakefile CHANGED
@@ -3,7 +3,7 @@ Bundler::GemHelper.install_tasks
3
3
 
4
4
  require 'rspec'
5
5
  require 'rspec/core/rake_task'
6
- Rspec::Core::RakeTask.new(:spec) do |spec|
6
+ RSpec::Core::RakeTask.new(:spec) do |spec|
7
7
  spec.pattern = 'spec/**/*_spec.rb'
8
8
  end
9
9
 
data/TODO CHANGED
@@ -1,11 +1,17 @@
1
+ * Support Mongoid / MongoMapper embedded documents
2
+
1
3
  * Add :foreign_key => ... option to update parents' votes
2
4
  - Reduce time to check relationships and foreign keys
3
5
  - More flexible
4
6
  - Need to change votable interface?
7
+
5
8
  * Support https://github.com/benmyles/mongomatic &
6
9
  https://github.com/carlosparamio/mongo_odm
7
10
  - Don't have scope
8
11
  - Don't have relationships
12
+
9
13
  * Add options hash validations
14
+
10
15
  * Refactor specs
16
+
11
17
  * More test cases for Tasks module
@@ -1,3 +1,4 @@
1
+ require 'voteable_mongo/helpers'
1
2
  require 'voteable_mongo/voteable'
2
3
  require 'voteable_mongo/voter'
3
4
  require 'voteable_mongo/tasks'
@@ -0,0 +1,15 @@
1
+ module Mongo
2
+ module Voteable
3
+ module Helpers
4
+
5
+ def self.try_to_convert_string_to_object_id(x)
6
+ x.is_a?(String) && BSON::ObjectId.legal?(x) ? BSON::ObjectId(x) : x
7
+ end
8
+
9
+ def self.get_mongo_id(x)
10
+ x.respond_to?(:id) ? x.id : x
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -1,3 +1,3 @@
1
1
  module VoteableMongo
2
- VERSION = '0.9.2'
2
+ VERSION = '0.9.3'
3
3
  end
@@ -16,26 +16,26 @@ module Mongo
16
16
  }
17
17
 
18
18
  included do
19
- include ::Mongo::Voteable::Voting
19
+ include Mongo::Voteable::Voting
20
20
 
21
21
  if defined?(Mongoid) && defined?(field)
22
- include ::Mongo::Voteable::Integrations::Mongoid
22
+ include Mongo::Voteable::Integrations::Mongoid
23
23
  elsif defined?(MongoMapper)
24
- include ::Mongo::Voteable::Integrations::MongoMapper
24
+ include Mongo::Voteable::Integrations::MongoMapper
25
25
  end
26
26
 
27
27
  scope :voted_by, lambda { |voter|
28
- voter_id = voter.is_a?(::BSON::ObjectId) ? voter : voter.id
28
+ voter_id = Helpers.get_mongo_id(voter)
29
29
  where('$or' => [{ 'votes.up' => voter_id }, { 'votes.down' => voter_id }])
30
30
  }
31
31
 
32
32
  scope :up_voted_by, lambda { |voter|
33
- voter_id = voter.is_a?(::BSON::ObjectId) ? voter : voter.id
33
+ voter_id = Helpers.get_mongo_id(voter)
34
34
  where('votes.up' => voter_id)
35
35
  }
36
36
 
37
37
  scope :down_voted_by, lambda { |voter|
38
- voter_id = voter.is_a?(::BSON::ObjectId) ? voter : voter.id
38
+ voter_id = Helpers.get_mongo_id(voter)
39
39
  where('votes.down' => voter_id)
40
40
  }
41
41
  end
@@ -140,9 +140,9 @@ module Mongo
140
140
 
141
141
  # Get a voted value on this votee
142
142
  #
143
- # @param [Mongoid Object, BSON::ObjectId] voter is Mongoid object or the id of the voter who made the vote
143
+ # @param voter is object or the id of the voter who made the vote
144
144
  def vote_value(voter)
145
- voter_id = voter.is_a?(BSON::ObjectId) ? voter : voter.id
145
+ voter_id = Helpers.get_mongo_id(voter)
146
146
  return :up if up_voter_ids.include?(voter_id)
147
147
  return :down if down_voter_ids.include?(voter_id)
148
148
  end
@@ -53,8 +53,8 @@ module Mongo
53
53
  private
54
54
  def validate_and_normalize_vote_options(options)
55
55
  options.symbolize_keys!
56
- options[:votee_id] = BSON::ObjectId(options[:votee_id]) if options[:votee_id].is_a?(String)
57
- options[:voter_id] = BSON::ObjectId(options[:voter_id]) if options[:voter_id].is_a?(String)
56
+ options[:votee_id] = Helpers.try_to_convert_string_to_object_id(options[:votee_id])
57
+ options[:voter_id] = Helpers.try_to_convert_string_to_object_id(options[:voter_id])
58
58
  options[:value] &&= options[:value].to_sym
59
59
  end
60
60
 
@@ -152,7 +152,7 @@ module Mongo
152
152
  def update_parent_votes(doc, options)
153
153
  VOTEABLE[name].each do |class_name, voteable|
154
154
  if metadata = voteable_relation(class_name)
155
- if parent_id = doc[voteable_foreign_key(metadata)]
155
+ if (parent_id = doc[voteable_foreign_key(metadata)]).present?
156
156
  parent_ids = parent_id.is_a?(Array) ? parent_id : [ parent_id ]
157
157
  class_name.constantize.collection.update(
158
158
  { '_id' => { '$in' => parent_ids } },
@@ -9,7 +9,9 @@ class Post
9
9
 
10
10
  has_and_belongs_to_many :categories
11
11
  has_many :comments
12
-
12
+
13
+ key :title
14
+
13
15
  voteable self, :up => +1, :down => -1, :index => true
14
16
  voteable Category, :up => +3, :down => -5, :update_counters => false
15
17
  end
@@ -3,8 +3,8 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
3
  describe Mongo::Voteable::Tasks do
4
4
  describe 'Mongo::Voteable::Tasks.init_stats' do
5
5
  before :all do
6
- @post1 = Post.create!
7
- @post2 = Post.create!
6
+ @post1 = Post.create!(:title => 'post1')
7
+ @post2 = Post.create!(:title => 'post2')
8
8
  end
9
9
 
10
10
  it 'after create votes has default value' do
@@ -35,9 +35,12 @@ describe Mongo::Voteable do
35
35
  @category1 = Category.create!(:name => 'xyz')
36
36
  @category2 = Category.create!(:name => 'abc')
37
37
 
38
- @post1 = Post.create!(:category_ids => [@category1.id, @category2.id])
39
- @post2 = Post.create!
40
-
38
+ @post1 = Post.create!(:title => 'post1')
39
+ @post2 = Post.create!(:title => 'post2')
40
+
41
+ @post1.category_ids = [@category1.id, @category2.id]
42
+ @post1.save!
43
+
41
44
  @comment = @post2.comments.create!
42
45
 
43
46
  @user1 = User.create!
@@ -2,8 +2,8 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
3
  describe Mongo::Voter do
4
4
  before :all do
5
- @post1 = Post.create!
6
- @post2 = Post.create!
5
+ @post1 = Post.create!(:title => 'post_1')
6
+ @post2 = Post.create!(:title => 'post_2')
7
7
 
8
8
  @user1 = User.create!
9
9
  @user2 = User.create!
@@ -12,10 +12,10 @@ Gem::Specification.new do |s|
12
12
  s.summary = %q{Add up / down voting ability to Mongoid and MongoMapper documents}
13
13
  s.description = %q{Add up / down voting ability to Mongoid and MongoMapper documents. Optimized for speed by using only ONE request to MongoDB to validate, update, and retrieve updated data.}
14
14
 
15
- s.add_development_dependency 'rspec', '~> 2.5.0'
16
- s.add_development_dependency 'mongoid', '~> 2.0.0'
17
- s.add_development_dependency 'mongo_mapper', '~> 0.9.0'
18
- s.add_development_dependency 'bson_ext', '~> 1.3.0'
15
+ s.add_development_dependency 'rspec', '~> 2.5'
16
+ s.add_development_dependency 'mongoid', '~> 2.0'
17
+ s.add_development_dependency 'mongo_mapper', '~> 0.9'
18
+ s.add_development_dependency 'bson_ext', '~> 1.4'
19
19
 
20
20
  s.rubyforge_project = 'voteable_mongo'
21
21
 
metadata CHANGED
@@ -1,71 +1,69 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: voteable_mongo
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.3
4
5
  prerelease:
5
- version: 0.9.2
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Alex Nguyen
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-05-07 00:00:00 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
12
+ date: 2011-10-08 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
16
15
  name: rspec
17
- prerelease: false
18
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &2166657880 !ruby/object:Gem::Requirement
19
17
  none: false
20
- requirements:
18
+ requirements:
21
19
  - - ~>
22
- - !ruby/object:Gem::Version
23
- version: 2.5.0
20
+ - !ruby/object:Gem::Version
21
+ version: '2.5'
24
22
  type: :development
25
- version_requirements: *id001
26
- - !ruby/object:Gem::Dependency
27
- name: mongoid
28
23
  prerelease: false
29
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *2166657880
25
+ - !ruby/object:Gem::Dependency
26
+ name: mongoid
27
+ requirement: &2166657380 !ruby/object:Gem::Requirement
30
28
  none: false
31
- requirements:
29
+ requirements:
32
30
  - - ~>
33
- - !ruby/object:Gem::Version
34
- version: 2.0.0
31
+ - !ruby/object:Gem::Version
32
+ version: '2.0'
35
33
  type: :development
36
- version_requirements: *id002
37
- - !ruby/object:Gem::Dependency
38
- name: mongo_mapper
39
34
  prerelease: false
40
- requirement: &id003 !ruby/object:Gem::Requirement
35
+ version_requirements: *2166657380
36
+ - !ruby/object:Gem::Dependency
37
+ name: mongo_mapper
38
+ requirement: &2166656920 !ruby/object:Gem::Requirement
41
39
  none: false
42
- requirements:
40
+ requirements:
43
41
  - - ~>
44
- - !ruby/object:Gem::Version
45
- version: 0.9.0
42
+ - !ruby/object:Gem::Version
43
+ version: '0.9'
46
44
  type: :development
47
- version_requirements: *id003
48
- - !ruby/object:Gem::Dependency
49
- name: bson_ext
50
45
  prerelease: false
51
- requirement: &id004 !ruby/object:Gem::Requirement
46
+ version_requirements: *2166656920
47
+ - !ruby/object:Gem::Dependency
48
+ name: bson_ext
49
+ requirement: &2166656460 !ruby/object:Gem::Requirement
52
50
  none: false
53
- requirements:
51
+ requirements:
54
52
  - - ~>
55
- - !ruby/object:Gem::Version
56
- version: 1.3.0
53
+ - !ruby/object:Gem::Version
54
+ version: '1.4'
57
55
  type: :development
58
- version_requirements: *id004
59
- description: Add up / down voting ability to Mongoid and MongoMapper documents. Optimized for speed by using only ONE request to MongoDB to validate, update, and retrieve updated data.
60
- email:
56
+ prerelease: false
57
+ version_requirements: *2166656460
58
+ description: Add up / down voting ability to Mongoid and MongoMapper documents. Optimized
59
+ for speed by using only ONE request to MongoDB to validate, update, and retrieve
60
+ updated data.
61
+ email:
61
62
  - alex@vinova.sg
62
63
  executables: []
63
-
64
64
  extensions: []
65
-
66
65
  extra_rdoc_files: []
67
-
68
- files:
66
+ files:
69
67
  - .gitignore
70
68
  - .rvmrc
71
69
  - .watchr
@@ -75,6 +73,7 @@ files:
75
73
  - Rakefile
76
74
  - TODO
77
75
  - lib/voteable_mongo.rb
76
+ - lib/voteable_mongo/helpers.rb
78
77
  - lib/voteable_mongo/integrations/mongo_mapper.rb
79
78
  - lib/voteable_mongo/integrations/mongoid.rb
80
79
  - lib/voteable_mongo/railtie.rb
@@ -100,32 +99,29 @@ files:
100
99
  - voteable_mongo.gemspec
101
100
  homepage: https://github.com/vinova/voteable_mongo
102
101
  licenses: []
103
-
104
102
  post_install_message:
105
103
  rdoc_options: []
106
-
107
- require_paths:
104
+ require_paths:
108
105
  - lib
109
- required_ruby_version: !ruby/object:Gem::Requirement
106
+ required_ruby_version: !ruby/object:Gem::Requirement
110
107
  none: false
111
- requirements:
112
- - - ">="
113
- - !ruby/object:Gem::Version
114
- version: "0"
115
- required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
113
  none: false
117
- requirements:
118
- - - ">="
119
- - !ruby/object:Gem::Version
120
- version: "0"
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
121
118
  requirements: []
122
-
123
119
  rubyforge_project: voteable_mongo
124
- rubygems_version: 1.8.1
120
+ rubygems_version: 1.8.10
125
121
  signing_key:
126
122
  specification_version: 3
127
123
  summary: Add up / down voting ability to Mongoid and MongoMapper documents
128
- test_files:
124
+ test_files:
129
125
  - spec/mongo_mapper/models/category.rb
130
126
  - spec/mongo_mapper/models/comment.rb
131
127
  - spec/mongo_mapper/models/post.rb