thumbs_up 0.5.7 → 0.6.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/Gemfile +1 -1
- data/README.md +5 -1
- data/Rakefile +10 -2
- data/lib/acts_as_voteable.rb +5 -4
- data/lib/generators/thumbs_up/templates/migration.rb +4 -4
- data/lib/thumbs_up/version.rb +1 -1
- data/lib/thumbs_up.rb +9 -0
- data/test/test_helper.rb +42 -21
- data/test/thumbs_up_test.rb +17 -8
- metadata +21 -5
data/Gemfile
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
source
|
|
1
|
+
source :rubygems
|
|
2
2
|
gemspec
|
data/README.md
CHANGED
|
@@ -80,7 +80,7 @@ Did the first user vote for the Car with id = 2 already?
|
|
|
80
80
|
u = User.first
|
|
81
81
|
u.vote_for(Car.find(2))
|
|
82
82
|
u.voted_on?(Car.find(2)) #=> true
|
|
83
|
-
|
|
83
|
+
|
|
84
84
|
Did the first user vote for or against the Car with id = 2?
|
|
85
85
|
|
|
86
86
|
u = User.first
|
|
@@ -92,6 +92,10 @@ Did the first user vote for or against the Car with id = 2?
|
|
|
92
92
|
|
|
93
93
|
You can easily retrieve voteable object collections based on the properties of their votes:
|
|
94
94
|
|
|
95
|
+
@items = Item.tally.limit(10).where('created_at > ?', 2.days.ago).having('COUNT(votes.id) < 10')
|
|
96
|
+
|
|
97
|
+
Or for MySQL:
|
|
98
|
+
|
|
95
99
|
@items = Item.tally.limit(10).where('created_at > ?', 2.days.ago).having('vote_count < 10')
|
|
96
100
|
|
|
97
101
|
This will select the Items with less than 10 votes, the votes having been cast within the last two days, with a limit of 10 items. *This tallies all votes, regardless of whether they are +1 (up) or -1 (down).* The #tally method returns an ActiveRecord Relation, so you can chain the normal method calls on to it.
|
data/Rakefile
CHANGED
|
@@ -24,10 +24,18 @@ end
|
|
|
24
24
|
task :build do
|
|
25
25
|
system "gem build thumbs_up.gemspec"
|
|
26
26
|
end
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
task :release => :build do
|
|
29
29
|
system "gem push thumbs_up-#{ThumbsUp::VERSION}.gem"
|
|
30
30
|
system "rm thumbs_up-#{ThumbsUp::VERSION}.gem"
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
task :
|
|
33
|
+
task :test_both_databases do
|
|
34
|
+
# Test both MySQL and Postgres.
|
|
35
|
+
ENV['DB'] = 'mysql'
|
|
36
|
+
Rake::Task['test'].execute
|
|
37
|
+
ENV['DB'] = 'postgres'
|
|
38
|
+
Rake::Task['test'].execute
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
task :default => :test_both_databases
|
data/lib/acts_as_voteable.rb
CHANGED
|
@@ -2,6 +2,7 @@ module ThumbsUp
|
|
|
2
2
|
module ActsAsVoteable #:nodoc:
|
|
3
3
|
|
|
4
4
|
def self.included(base)
|
|
5
|
+
base.extend ThumbsUp::Base
|
|
5
6
|
base.extend ClassMethods
|
|
6
7
|
end
|
|
7
8
|
|
|
@@ -15,7 +16,7 @@ module ThumbsUp
|
|
|
15
16
|
end
|
|
16
17
|
|
|
17
18
|
module SingletonMethods
|
|
18
|
-
|
|
19
|
+
|
|
19
20
|
# Calculate the plusminus for a group of voteables in one database query.
|
|
20
21
|
# This returns an Arel relation, so you can add conditions as you like chained on to
|
|
21
22
|
# this method call.
|
|
@@ -27,10 +28,10 @@ module ThumbsUp
|
|
|
27
28
|
t = t.order("plusminus_tally DESC")
|
|
28
29
|
t = t.group("#{self.table_name}.id")
|
|
29
30
|
t = t.select("#{self.table_name}.*")
|
|
30
|
-
t = t.select("SUM(CASE
|
|
31
|
+
t = t.select("SUM(CASE WHEN #{Vote.table_name}.vote THEN 1 ELSE -1 END) AS plusminus_tally")
|
|
31
32
|
if params[:separate_updown]
|
|
32
|
-
t = t.select("SUM(CASE
|
|
33
|
-
t = t.select("SUM(CASE
|
|
33
|
+
t = t.select("SUM(CASE WHEN #{Vote.table_name}.vote THEN 1 ELSE 0 END) AS up")
|
|
34
|
+
t = t.select("SUM(CASE WHEN #{Vote.table_name}.vote THEN 0 ELSE 1 END) AS down")
|
|
34
35
|
end
|
|
35
36
|
t = t.select("COUNT(#{Vote.table_name}.id) AS vote_count")
|
|
36
37
|
end
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
class ThumbsUpMigration < ActiveRecord::Migration
|
|
2
2
|
def self.up
|
|
3
3
|
create_table :votes, :force => true do |t|
|
|
4
|
-
|
|
5
|
-
t.boolean :vote, :default => false
|
|
4
|
+
|
|
5
|
+
t.boolean :vote, :default => false, :null => false
|
|
6
6
|
t.references :voteable, :polymorphic => true, :null => false
|
|
7
7
|
t.references :voter, :polymorphic => true
|
|
8
8
|
t.timestamps
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
add_index :votes, [:voter_id, :voter_type]
|
|
13
13
|
add_index :votes, [:voteable_id, :voteable_type]
|
|
14
14
|
|
|
15
15
|
<% if options[:unique_voting] == true %>
|
|
16
|
-
# Comment out the line below to allow multiple votes per voter on a single entity.
|
|
16
|
+
# Comment out the line below to allow multiple votes per voter on a single entity.
|
|
17
17
|
add_index :votes, [:voter_id, :voter_type, :voteable_id, :voteable_type], :unique => true, :name => 'fk_one_vote_per_user_per_entity'
|
|
18
18
|
<% end %>
|
|
19
19
|
end
|
data/lib/thumbs_up/version.rb
CHANGED
data/lib/thumbs_up.rb
CHANGED
|
@@ -2,6 +2,15 @@ require 'acts_as_voteable'
|
|
|
2
2
|
require 'acts_as_voter'
|
|
3
3
|
require 'has_karma'
|
|
4
4
|
|
|
5
|
+
module ThumbsUp
|
|
6
|
+
module Base
|
|
7
|
+
# Check if we're connected to a MySQL database.
|
|
8
|
+
def mysql?
|
|
9
|
+
ActiveRecord::Base.connection.adapter_name == 'MySQL'
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
5
14
|
ActiveRecord::Base.send(:include, ThumbsUp::ActsAsVoteable)
|
|
6
15
|
ActiveRecord::Base.send(:include, ThumbsUp::ActsAsVoter)
|
|
7
16
|
ActiveRecord::Base.send(:include, ThumbsUp::Karma)
|
data/test/test_helper.rb
CHANGED
|
@@ -7,26 +7,47 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
|
7
7
|
|
|
8
8
|
require 'active_record'
|
|
9
9
|
|
|
10
|
-
if ENV['
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
if ENV['DB'] == 'mysql'
|
|
11
|
+
if ENV['TRAVIS']
|
|
12
|
+
config = {
|
|
13
|
+
:adapter => 'mysql2',
|
|
14
|
+
:database => 'thumbs_up_test',
|
|
15
|
+
:username => 'root'
|
|
16
|
+
}
|
|
17
|
+
else
|
|
18
|
+
config = {
|
|
19
|
+
:adapter => 'mysql2',
|
|
20
|
+
:database => 'thumbs_up_test',
|
|
21
|
+
:username => 'test',
|
|
22
|
+
:password => 'test',
|
|
23
|
+
:socket => '/tmp/mysql.sock'
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
ActiveRecord::Base.establish_connection(config)
|
|
28
|
+
ActiveRecord::Base.connection.drop_database config[:database] rescue nil
|
|
29
|
+
ActiveRecord::Base.connection.create_database config[:database]
|
|
30
|
+
ActiveRecord::Base.establish_connection(config)
|
|
16
31
|
else
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
32
|
+
if ENV['TRAVIS']
|
|
33
|
+
config = {
|
|
34
|
+
:adapter => 'postgresql',
|
|
35
|
+
:database => 'thumbs_up_test',
|
|
36
|
+
:username => 'postgres'
|
|
37
|
+
}
|
|
38
|
+
else
|
|
39
|
+
config = {
|
|
40
|
+
:adapter => 'postgresql',
|
|
41
|
+
:database => 'thumbs_up_test',
|
|
42
|
+
:username => 'test'
|
|
43
|
+
}
|
|
44
|
+
end
|
|
25
45
|
|
|
26
|
-
ActiveRecord::Base.establish_connection(config)
|
|
27
|
-
ActiveRecord::Base.connection.drop_database config[:database]
|
|
28
|
-
ActiveRecord::Base.connection.create_database config[:database]
|
|
29
|
-
ActiveRecord::Base.establish_connection(config)
|
|
46
|
+
ActiveRecord::Base.establish_connection(config.merge({ :database => 'postgres' }))
|
|
47
|
+
ActiveRecord::Base.connection.drop_database config[:database]
|
|
48
|
+
ActiveRecord::Base.connection.create_database config[:database]
|
|
49
|
+
ActiveRecord::Base.establish_connection(config)
|
|
50
|
+
end
|
|
30
51
|
|
|
31
52
|
ActiveRecord::Migration.verbose = false
|
|
32
53
|
|
|
@@ -41,14 +62,14 @@ ActiveRecord::Schema.define do
|
|
|
41
62
|
add_index :votes, [:voter_id, :voter_type]
|
|
42
63
|
add_index :votes, [:voteable_id, :voteable_type]
|
|
43
64
|
|
|
44
|
-
# Comment out the line below to allow multiple votes per voter on a single entity.
|
|
65
|
+
# Comment out the line below to allow multiple votes per voter on a single entity.
|
|
45
66
|
add_index :votes, [:voter_id, :voter_type, :voteable_id, :voteable_type], :unique => true, :name => 'fk_one_vote_per_user_per_entity'
|
|
46
|
-
|
|
67
|
+
|
|
47
68
|
create_table :users, :force => true do |t|
|
|
48
69
|
t.string :name
|
|
49
70
|
t.timestamps
|
|
50
71
|
end
|
|
51
|
-
|
|
72
|
+
|
|
52
73
|
create_table :items, :force => true do |t|
|
|
53
74
|
t.integer :user_id
|
|
54
75
|
t.string :name
|
data/test/thumbs_up_test.rb
CHANGED
|
@@ -24,6 +24,8 @@ class TestThumbsUp < Test::Unit::TestCase
|
|
|
24
24
|
assert_equal 0, user_for.vote_count(:down)
|
|
25
25
|
assert_equal true, user_for.voted_which_way?(item, :up)
|
|
26
26
|
assert_equal false, user_for.voted_which_way?(item, :down)
|
|
27
|
+
assert_equal 1, user_for.votes.where(:voteable_type => 'Item').count
|
|
28
|
+
assert_equal 0, user_for.votes.where(:voteable_type => 'AnotherItem').count
|
|
27
29
|
assert_raises(ArgumentError) do
|
|
28
30
|
user_for.voted_which_way?(item, :foo)
|
|
29
31
|
end
|
|
@@ -226,8 +228,13 @@ class TestThumbsUp < Test::Unit::TestCase
|
|
|
226
228
|
|
|
227
229
|
assert_not_nil user.vote_for(item)
|
|
228
230
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
+
if ActiveRecord::Base.connection.adapter_name == 'MySQL'
|
|
232
|
+
assert (Item.plusminus_tally.having('vote_count > 0').include? item)
|
|
233
|
+
assert (not Item.plusminus_tally.having('vote_count > 0').include? item_not_included)
|
|
234
|
+
else
|
|
235
|
+
assert (Item.plusminus_tally.having('COUNT(votes.id) > 0').include? item)
|
|
236
|
+
assert (not Item.plusminus_tally.having('COUNT(votes.id) > 0').include? item_not_included)
|
|
237
|
+
end
|
|
231
238
|
end
|
|
232
239
|
|
|
233
240
|
def test_plusminus_tally_voting_for
|
|
@@ -236,8 +243,9 @@ class TestThumbsUp < Test::Unit::TestCase
|
|
|
236
243
|
|
|
237
244
|
assert_not_nil user1.vote_for(item)
|
|
238
245
|
|
|
239
|
-
|
|
240
|
-
assert_equal 1, Item.plusminus_tally[0].
|
|
246
|
+
# https://github.com/rails/rails/issues/1718
|
|
247
|
+
assert_equal 1, Item.plusminus_tally[0].vote_count.to_i
|
|
248
|
+
assert_equal 1, Item.plusminus_tally[0].plusminus.to_i
|
|
241
249
|
end
|
|
242
250
|
|
|
243
251
|
def test_plusminus_tally_voting_against
|
|
@@ -248,8 +256,9 @@ class TestThumbsUp < Test::Unit::TestCase
|
|
|
248
256
|
assert_not_nil user1.vote_against(item)
|
|
249
257
|
assert_not_nil user2.vote_against(item)
|
|
250
258
|
|
|
251
|
-
|
|
252
|
-
assert_equal
|
|
259
|
+
# https://github.com/rails/rails/issues/1718
|
|
260
|
+
assert_equal 2, Item.plusminus_tally[0].vote_count.to_i
|
|
261
|
+
assert_equal -2, Item.plusminus_tally[0].plusminus.to_i
|
|
253
262
|
end
|
|
254
263
|
|
|
255
264
|
def test_plusminus_tally_default_ordering
|
|
@@ -268,7 +277,7 @@ class TestThumbsUp < Test::Unit::TestCase
|
|
|
268
277
|
assert_equal item_for, Item.plusminus_tally[1]
|
|
269
278
|
assert_equal item_against, Item.plusminus_tally[2]
|
|
270
279
|
end
|
|
271
|
-
|
|
280
|
+
|
|
272
281
|
def test_plusminus_tally_limit
|
|
273
282
|
users = (0..9).map{ |u| User.create(:name => "User #{u}") }
|
|
274
283
|
items = (0..9).map{ |u| Item.create(:name => "Item #{u}", :description => "Item #{u}") }
|
|
@@ -305,7 +314,7 @@ class TestThumbsUp < Test::Unit::TestCase
|
|
|
305
314
|
users = (0..1).map{ |u| User.create(:name => "User #{u}") }
|
|
306
315
|
items = (0..1).map{ |u| users[0].items.create(:name => "Item #{u}", :description => "Item #{u}") }
|
|
307
316
|
users.each{ |u| items.each { |i| u.vote_for(i) } }
|
|
308
|
-
|
|
317
|
+
|
|
309
318
|
assert_equal 4, users[0].karma
|
|
310
319
|
assert_equal 0, users[1].karma
|
|
311
320
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: thumbs_up
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -14,7 +14,7 @@ authors:
|
|
|
14
14
|
autorequire:
|
|
15
15
|
bindir: bin
|
|
16
16
|
cert_chain: []
|
|
17
|
-
date: 2012-
|
|
17
|
+
date: 2012-07-29 00:00:00.000000000 Z
|
|
18
18
|
dependencies:
|
|
19
19
|
- !ruby/object:Gem::Dependency
|
|
20
20
|
name: activerecord
|
|
@@ -96,6 +96,22 @@ dependencies:
|
|
|
96
96
|
- - ! '>='
|
|
97
97
|
- !ruby/object:Gem::Version
|
|
98
98
|
version: '0'
|
|
99
|
+
- !ruby/object:Gem::Dependency
|
|
100
|
+
name: pg
|
|
101
|
+
requirement: !ruby/object:Gem::Requirement
|
|
102
|
+
none: false
|
|
103
|
+
requirements:
|
|
104
|
+
- - ! '>='
|
|
105
|
+
- !ruby/object:Gem::Version
|
|
106
|
+
version: '0'
|
|
107
|
+
type: :development
|
|
108
|
+
prerelease: false
|
|
109
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
110
|
+
none: false
|
|
111
|
+
requirements:
|
|
112
|
+
- - ! '>='
|
|
113
|
+
- !ruby/object:Gem::Version
|
|
114
|
+
version: '0'
|
|
99
115
|
- !ruby/object:Gem::Dependency
|
|
100
116
|
name: rake
|
|
101
117
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -150,7 +166,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
150
166
|
version: '0'
|
|
151
167
|
segments:
|
|
152
168
|
- 0
|
|
153
|
-
hash:
|
|
169
|
+
hash: -1660029981921768377
|
|
154
170
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
155
171
|
none: false
|
|
156
172
|
requirements:
|
|
@@ -159,10 +175,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
159
175
|
version: '0'
|
|
160
176
|
segments:
|
|
161
177
|
- 0
|
|
162
|
-
hash:
|
|
178
|
+
hash: -1660029981921768377
|
|
163
179
|
requirements: []
|
|
164
180
|
rubyforge_project:
|
|
165
|
-
rubygems_version: 1.8.
|
|
181
|
+
rubygems_version: 1.8.24
|
|
166
182
|
signing_key:
|
|
167
183
|
specification_version: 3
|
|
168
184
|
summary: Voting for ActiveRecord with multiple vote sources and karma calculation.
|