thumbs_up 0.5.7 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|