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.
- data/CHANGELOG.rdoc +3 -0
- data/README.rdoc +22 -19
- data/Rakefile +1 -1
- data/TODO +6 -0
- data/lib/voteable_mongo.rb +1 -0
- data/lib/voteable_mongo/helpers.rb +15 -0
- data/lib/voteable_mongo/version.rb +1 -1
- data/lib/voteable_mongo/voteable.rb +8 -8
- data/lib/voteable_mongo/voting.rb +3 -3
- data/spec/mongoid/models/post.rb +3 -1
- data/spec/voteable_mongo/tasks_spec.rb +2 -2
- data/spec/voteable_mongo/voteable_spec.rb +6 -3
- data/spec/voteable_mongo/voter_spec.rb +2 -2
- data/voteable_mongo.gemspec +4 -4
- metadata +53 -57
data/CHANGELOG.rdoc
CHANGED
data/README.rdoc
CHANGED
@@ -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
|
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
|
-
|
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
|
-
|
18
|
+
* Don't have to maintain additional votes table or votes collection.
|
23
19
|
|
24
|
-
|
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
|
31
|
+
* http://zheye.org
|
29
32
|
|
30
33
|
== Installation
|
31
34
|
|
32
|
-
=== Rails 3.
|
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
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
|
data/lib/voteable_mongo.rb
CHANGED
@@ -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
|
@@ -16,26 +16,26 @@ module Mongo
|
|
16
16
|
}
|
17
17
|
|
18
18
|
included do
|
19
|
-
include
|
19
|
+
include Mongo::Voteable::Voting
|
20
20
|
|
21
21
|
if defined?(Mongoid) && defined?(field)
|
22
|
-
include
|
22
|
+
include Mongo::Voteable::Integrations::Mongoid
|
23
23
|
elsif defined?(MongoMapper)
|
24
|
-
include
|
24
|
+
include Mongo::Voteable::Integrations::MongoMapper
|
25
25
|
end
|
26
26
|
|
27
27
|
scope :voted_by, lambda { |voter|
|
28
|
-
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 =
|
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 =
|
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
|
143
|
+
# @param voter is object or the id of the voter who made the vote
|
144
144
|
def vote_value(voter)
|
145
|
-
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] =
|
57
|
-
options[:voter_id] =
|
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 } },
|
data/spec/mongoid/models/post.rb
CHANGED
@@ -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!(:
|
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!
|
data/voteable_mongo.gemspec
CHANGED
@@ -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
|
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.
|
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
|
-
|
14
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
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
|
-
|
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
|
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
|
-
|
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.
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.4'
|
57
55
|
type: :development
|
58
|
-
|
59
|
-
|
60
|
-
|
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:
|
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:
|
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.
|
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
|