voteable_mongo 0.9.1 → 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +4 -0
- data/README.rdoc +26 -11
- data/TODO +8 -0
- data/lib/voteable_mongo.rb +0 -2
- data/lib/voteable_mongo/railtie.rb +3 -1
- data/lib/voteable_mongo/tasks.rb +1 -1
- data/lib/voteable_mongo/version.rb +1 -1
- data/lib/voteable_mongo/voter.rb +4 -6
- data/lib/voteable_mongo/voting.rb +10 -7
- data/spec/spec_helper.rb +3 -3
- data/spec/voteable_mongo/voteable_spec.rb +4 -0
- data/spec/voteable_mongo/voter_spec.rb +3 -3
- data/voteable_mongo.gemspec +2 -2
- metadata +5 -5
data/CHANGELOG.rdoc
CHANGED
data/README.rdoc
CHANGED
@@ -1,14 +1,29 @@
|
|
1
1
|
= Voteable Mongo
|
2
2
|
|
3
|
-
voteable_mongo allows you to make your Mongoid::Document or MongoMapper::Document objects voteable
|
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
|
-
|
5
|
+
Initial idea based on http://cookbook.mongodb.org/patterns/votes
|
6
6
|
|
7
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
|
+
Visit benchmarks at https://github.com/vinova/voteable_benchmarks
|
10
11
|
|
11
|
-
|
12
|
+
== Why voteable_mongo?
|
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
|
19
|
+
|
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.
|
21
|
+
|
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 ...
|
23
|
+
|
24
|
+
So use voteable_mongo and save your database requests for other other tasks.
|
25
|
+
|
26
|
+
== Sites using voteable_mongo
|
12
27
|
* http://www.amorveneris.com
|
13
28
|
* http://zheye.org (https://github.com/huacnlee/quora)
|
14
29
|
|
@@ -108,7 +123,7 @@ Is equivalent to
|
|
108
123
|
@post.vote(:voter => @user, :value => :up)
|
109
124
|
|
110
125
|
In case you don't need to init voter and / or votee objects you can
|
111
|
-
@user.vote(:
|
126
|
+
@user.vote(:votee_class => Post, :votee_id => post_id, :value => :down)
|
112
127
|
@post.vote(:voter_id => user_id, :value => :up)
|
113
128
|
Post.vote(:voter_id => user_id, :votee_id => post_id, :value => :up)
|
114
129
|
|
@@ -132,14 +147,14 @@ Note: vote function always return updated votee object
|
|
132
147
|
=== Get vote_value
|
133
148
|
|
134
149
|
@user.vote_value(@post)
|
135
|
-
@user.vote_value(:
|
150
|
+
@user.vote_value(:votee_class => Post, :votee_id => post_id)
|
136
151
|
@post.vote_value(@user)
|
137
152
|
@post.vote_value(user_id)
|
138
153
|
|
139
154
|
=== Check if voted?
|
140
155
|
|
141
156
|
@user.voted?(@post)
|
142
|
-
@user.voted?(:
|
157
|
+
@user.voted?(:votee_class => Post, :votee_id => post_id)
|
143
158
|
@post.voted_by?(@user)
|
144
159
|
@post.voted_by?(user_id)
|
145
160
|
|
@@ -180,16 +195,16 @@ Rails
|
|
180
195
|
Ruby
|
181
196
|
Mongo::Voteable::Tasks::init_stats
|
182
197
|
|
183
|
-
=== Migrate from version < 0.7.0
|
198
|
+
=== Migrate from voteable_mongoid version < 0.7.0
|
184
199
|
Rails
|
185
200
|
rake mongo:voteable:migrate_old_votes
|
186
201
|
Ruby
|
187
202
|
Mongo::Voteable::Tasks.migrate_old_votes
|
188
203
|
|
189
204
|
== Credits
|
190
|
-
* Alex Nguyen
|
191
|
-
*
|
205
|
+
* Alex Nguyen - Author
|
206
|
+
* https://github.com/vinova/voteable_mongo/contributors
|
192
207
|
|
193
|
-
Copyright (c) 2010-2011 Vinova Pte Ltd
|
208
|
+
Copyright (c) 2010-2011 Vinova Pte Ltd
|
194
209
|
|
195
210
|
Licensed under the MIT license.
|
data/TODO
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
* Add :foreign_key => ... option to update parents' votes
|
2
|
+
- Reduce time to check relationships and foreign keys
|
3
|
+
- More flexible
|
4
|
+
- Need to change votable interface?
|
5
|
+
* Support https://github.com/benmyles/mongomatic &
|
6
|
+
https://github.com/carlosparamio/mongo_odm
|
7
|
+
- Don't have scope
|
8
|
+
- Don't have relationships
|
1
9
|
* Add options hash validations
|
2
10
|
* Refactor specs
|
3
11
|
* More test cases for Tasks module
|
data/lib/voteable_mongo.rb
CHANGED
data/lib/voteable_mongo/tasks.rb
CHANGED
data/lib/voteable_mongo/voter.rb
CHANGED
@@ -23,7 +23,7 @@ module Mongo
|
|
23
23
|
votee_class = votee.class
|
24
24
|
votee_id = votee.id
|
25
25
|
else
|
26
|
-
votee_class = options[:
|
26
|
+
votee_class = options[:votee_class]
|
27
27
|
votee_id = options[:votee_id]
|
28
28
|
end
|
29
29
|
end
|
@@ -39,9 +39,7 @@ module Mongo
|
|
39
39
|
votee = unless options.is_a?(Hash)
|
40
40
|
options
|
41
41
|
else
|
42
|
-
options[:votee] || options[:
|
43
|
-
:_id => options[:votee_id]
|
44
|
-
).first
|
42
|
+
options[:votee] || options[:votee_class].find(options[:votee_id])
|
45
43
|
end
|
46
44
|
votee.vote_value(_id)
|
47
45
|
end
|
@@ -74,7 +72,7 @@ module Mongo
|
|
74
72
|
options[:votee_id] = votee.id
|
75
73
|
votee_class = votee.class
|
76
74
|
else
|
77
|
-
votee_class = options[:
|
75
|
+
votee_class = options[:votee_class]
|
78
76
|
end
|
79
77
|
|
80
78
|
if options[:value].nil?
|
@@ -87,7 +85,7 @@ module Mongo
|
|
87
85
|
options[:voter] = self
|
88
86
|
options[:voter_id] = id
|
89
87
|
|
90
|
-
(
|
88
|
+
(votee || votee_class).vote(options)
|
91
89
|
end
|
92
90
|
end
|
93
91
|
|
@@ -27,13 +27,16 @@ module Mongo
|
|
27
27
|
new_vote_query_and_update(options)
|
28
28
|
end
|
29
29
|
|
30
|
-
#
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
30
|
+
# http://www.mongodb.org/display/DOCS/findAndModify+Command
|
31
|
+
begin
|
32
|
+
doc = voteable_collection.find_and_modify(
|
33
|
+
:query => query,
|
34
|
+
:update => update,
|
35
|
+
:new => true
|
36
|
+
)
|
37
|
+
rescue Mongo::OperationFailure
|
38
|
+
doc = nil
|
39
|
+
end
|
37
40
|
|
38
41
|
if doc
|
39
42
|
update_parent_votes(doc, options) if options[:voteable][:update_parents]
|
data/spec/spec_helper.rb
CHANGED
@@ -2,8 +2,8 @@ require 'rubygems'
|
|
2
2
|
require 'bundler'
|
3
3
|
Bundler.setup
|
4
4
|
|
5
|
-
|
6
|
-
if rand > 0.
|
5
|
+
# TODO: Need better solution
|
6
|
+
if rand > 0.5
|
7
7
|
puts 'Mongoid'
|
8
8
|
require 'mongoid'
|
9
9
|
models_folder = File.join(File.dirname(__FILE__), 'mongoid/models')
|
@@ -33,5 +33,5 @@ Dir[ File.join(models_folder, '*.rb') ].each { |file|
|
|
33
33
|
require file
|
34
34
|
file_name = File.basename(file).sub('.rb', '')
|
35
35
|
klass = file_name.classify.constantize
|
36
|
-
|
36
|
+
klass.collection.drop
|
37
37
|
}
|
@@ -44,6 +44,10 @@ describe Mongo::Voteable do
|
|
44
44
|
@user2 = User.create!
|
45
45
|
end
|
46
46
|
|
47
|
+
it "vote for unexisting post" do
|
48
|
+
@user1.vote(:votee_class => Post, :votee_id => BSON::ObjectId.new, :value => :up).should == false
|
49
|
+
end
|
50
|
+
|
47
51
|
context "just created" do
|
48
52
|
it 'votes_count, up_votes_count, down_votes_count, votes_point should be zero' do
|
49
53
|
@category1.up_votes_count.should == 0
|
@@ -35,7 +35,7 @@ describe Mongo::Voter do
|
|
35
35
|
|
36
36
|
context 'user1 vote up post1 the first time' do
|
37
37
|
before :all do
|
38
|
-
@user1.vote(:revote => '', :votee_id => @post1.id, :
|
38
|
+
@user1.vote(:revote => '', :votee_id => @post1.id, :votee_class => Post, :value => :up)
|
39
39
|
@post1.reload
|
40
40
|
end
|
41
41
|
|
@@ -44,10 +44,10 @@ describe Mongo::Voter do
|
|
44
44
|
@post1.votes_point.should == 1
|
45
45
|
|
46
46
|
@user1.vote_value(@post1).should == :up
|
47
|
-
@user2.vote_value(:
|
47
|
+
@user2.vote_value(:votee_class => Post, :votee_id => @post1.id).should be_nil
|
48
48
|
|
49
49
|
@user1.should be_voted(@post1)
|
50
|
-
@user2.should_not be_voted(:
|
50
|
+
@user2.should_not be_voted(:votee_class => Post, :votee_id => @post1.id)
|
51
51
|
|
52
52
|
Post.voted_by(@user1).to_a.should == [ @post1 ]
|
53
53
|
Post.up_voted_by(@user1).to_a.should == [ @post1 ]
|
data/voteable_mongo.gemspec
CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.authors = ['Alex Nguyen']
|
10
10
|
s.email = ['alex@vinova.sg']
|
11
11
|
s.homepage = 'https://github.com/vinova/voteable_mongo'
|
12
|
-
s.summary = %q{Add
|
13
|
-
s.description = %q{Add
|
12
|
+
s.summary = %q{Add up / down voting ability to Mongoid and MongoMapper documents}
|
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
15
|
s.add_development_dependency 'rspec', '~> 2.5.0'
|
16
16
|
s.add_development_dependency 'mongoid', '~> 2.0.0'
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: voteable_mongo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.9.
|
5
|
+
version: 0.9.2
|
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-
|
13
|
+
date: 2011-05-07 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec
|
@@ -56,7 +56,7 @@ dependencies:
|
|
56
56
|
version: 1.3.0
|
57
57
|
type: :development
|
58
58
|
version_requirements: *id004
|
59
|
-
description: Add
|
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
60
|
email:
|
61
61
|
- alex@vinova.sg
|
62
62
|
executables: []
|
@@ -121,10 +121,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
121
121
|
requirements: []
|
122
122
|
|
123
123
|
rubyforge_project: voteable_mongo
|
124
|
-
rubygems_version: 1.
|
124
|
+
rubygems_version: 1.8.1
|
125
125
|
signing_key:
|
126
126
|
specification_version: 3
|
127
|
-
summary: Add
|
127
|
+
summary: Add up / down voting ability to Mongoid and MongoMapper documents
|
128
128
|
test_files:
|
129
129
|
- spec/mongo_mapper/models/category.rb
|
130
130
|
- spec/mongo_mapper/models/comment.rb
|