ibham 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +0 -2
- data/CHANGELOG.md +7 -0
- data/README.md +1 -0
- data/Rakefile +1 -1
- data/ibham.gemspec +0 -1
- data/lib/generators/ibham/templates/migration.rb +2 -2
- data/lib/ibham.rb +2 -1
- data/lib/ibham/acts_as_voteable.rb +46 -5
- data/lib/ibham/acts_as_voter.rb +35 -5
- data/lib/ibham/version.rb +1 -1
- data/lib/models/vote.rb +7 -4
- data/spec/models/vote_spec.rb +5 -5
- data/spec/modules/acts_as_voteable_spec.rb +23 -2
- data/spec/modules/acts_as_voter_spec.rb +2 -2
- data/spec/spec_helper.rb +16 -7
- metadata +9 -19
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -70,6 +70,7 @@ To retrieve the votes:
|
|
70
70
|
item.up_percentage # Return the percentage of positive votes
|
71
71
|
item.down_percentage # Return the percentage of negative votes
|
72
72
|
|
73
|
+
For more information visit [[the documentation page](http://rubydoc.info/github/bloc40/ibham/master/frames)]
|
73
74
|
## Contributing
|
74
75
|
|
75
76
|
1. Fork it
|
data/Rakefile
CHANGED
data/ibham.gemspec
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
class IbhamCreateVotes < ActiveRecord::Migration
|
2
2
|
def change
|
3
3
|
create_table :votes do |t|
|
4
|
-
t.references :voter, polymorphic
|
5
|
-
t.references :voteable, polymorphic
|
4
|
+
t.references :voter, :polymorphic => true
|
5
|
+
t.references :voteable, :polymorphic => true
|
6
6
|
t.integer :value
|
7
7
|
|
8
8
|
t.timestamps
|
data/lib/ibham.rb
CHANGED
@@ -3,6 +3,12 @@ module Ibham
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
module ClassMethods
|
6
|
+
|
7
|
+
# To turn an abject to a voteable, call <tt>acts_as_voteable</tt> in the Active Record model class.
|
8
|
+
#
|
9
|
+
# class Item < ActiveRecord::Base
|
10
|
+
# acts_as_voteable
|
11
|
+
# end
|
6
12
|
def acts_as_voteable
|
7
13
|
class_eval do
|
8
14
|
include Voteable
|
@@ -14,23 +20,58 @@ module Ibham
|
|
14
20
|
extend ActiveSupport::Concern
|
15
21
|
|
16
22
|
included do
|
17
|
-
has_many :votes, as
|
23
|
+
has_many :votes, :as => :voteable, :dependent => :destroy
|
18
24
|
end
|
19
25
|
|
26
|
+
# To ruturn the count of positive votes, call <tt>up_votes</tt> on the voteable object.
|
27
|
+
#
|
28
|
+
# item.up_votes
|
20
29
|
def up_votes
|
21
|
-
votes.where(value
|
30
|
+
votes.where(:value => ALLOWED_VALUE).count
|
22
31
|
end
|
23
32
|
|
33
|
+
# To ruturn the count of negative votes, call <tt>down_votes</tt> on the voteable object.
|
34
|
+
#
|
35
|
+
# item.down_votes
|
24
36
|
def down_votes
|
25
|
-
votes.where(value
|
37
|
+
votes.where(:value => -ALLOWED_VALUE).count
|
26
38
|
end
|
27
39
|
|
40
|
+
# To ruturn the percentage of positive votes, call <tt>up_percentage</tt> on the voteable object.
|
41
|
+
# This is ideal to use with sparkbars.
|
42
|
+
#
|
43
|
+
# item.up_percentage
|
28
44
|
def up_percentage
|
29
|
-
up_votes * 100 / votes.count.to_f
|
45
|
+
(up_votes * 100 / (votes.count.to_f + DELTA)).round
|
30
46
|
end
|
31
47
|
|
48
|
+
# To ruturn the percentage of positive votes, call <tt>down_percentage</tt> on the voteable object.
|
49
|
+
# This is ideal to use with sparkbars.
|
50
|
+
#
|
51
|
+
# item.down_percentage
|
32
52
|
def down_percentage
|
33
|
-
100
|
53
|
+
(down_votes * 100 / (votes.count.to_f + DELTA)).round
|
54
|
+
end
|
55
|
+
|
56
|
+
# To get the list of voters, call <tt>voters</tt> on the voteable object.
|
57
|
+
#
|
58
|
+
# item.voters
|
59
|
+
def voters
|
60
|
+
votes.map(&:voter)
|
61
|
+
end
|
62
|
+
|
63
|
+
# To get the list of voters who casted positive votes, call <tt>up_voters</tt> on the voteable object.
|
64
|
+
#
|
65
|
+
# item.up_voters
|
66
|
+
def up_voters
|
67
|
+
votes.where(:value => ALLOWED_VALUE).map(&:voter)
|
68
|
+
end
|
69
|
+
|
70
|
+
# To get the list of voters who casted negative votes, call <tt>down_voters</tt> on the voteable object.
|
71
|
+
#
|
72
|
+
# item.down_voters
|
73
|
+
def down_voters
|
74
|
+
votes.where(:value => -ALLOWED_VALUE).map(&:voter)
|
34
75
|
end
|
35
76
|
end
|
36
77
|
end
|
data/lib/ibham/acts_as_voter.rb
CHANGED
@@ -3,6 +3,12 @@ module Ibham
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
module ClassMethods
|
6
|
+
|
7
|
+
# To turn an abject to a voter, call <tt>acts_as_voter</tt> in the Active Record model class.
|
8
|
+
#
|
9
|
+
# class User < ActiveRecord::Base
|
10
|
+
# acts_as_voter
|
11
|
+
# end
|
6
12
|
def acts_as_voter
|
7
13
|
class_eval do
|
8
14
|
include Voter
|
@@ -14,23 +20,47 @@ module Ibham
|
|
14
20
|
extend ActiveSupport::Concern
|
15
21
|
|
16
22
|
included do
|
17
|
-
has_many :votes, as
|
23
|
+
has_many :votes, :as => :voter, :dependent => :destroy
|
18
24
|
end
|
19
25
|
|
26
|
+
# To check if the voter (the user for example) can vote for this item,
|
27
|
+
# call <tt>can_vote_for?</tt> on the voter with the object to vote for.
|
28
|
+
#
|
29
|
+
# user.can_vote_for?(item)
|
30
|
+
#
|
31
|
+
# This will return either true for false
|
20
32
|
def can_vote_for?(voteable)
|
21
|
-
votes.build(voteable
|
33
|
+
votes.build(:voteable => voteable, :value => ALLOWED_VALUE).valid?
|
22
34
|
end
|
23
35
|
|
36
|
+
# To cast a positive vote, the voter (e.g. the use) calls <tt>vote_up</tt>
|
37
|
+
# with the object to vote for.
|
38
|
+
#
|
39
|
+
# user.vote_up(item)
|
40
|
+
#
|
41
|
+
# This will add a new record with a positive vote for this item by this user in the votes table.
|
24
42
|
def vote_up(voteable)
|
25
|
-
votes.create(voteable
|
43
|
+
votes.create(:voteable => voteable, :value => ALLOWED_VALUE)
|
26
44
|
end
|
27
45
|
|
46
|
+
# To cast a negative vote, the voter (e.g. the use) can call <tt>vote_up</tt>
|
47
|
+
# with the object to vote for.
|
48
|
+
#
|
49
|
+
# user.vote_up(item)
|
50
|
+
#
|
51
|
+
# This will add a new record with a negative vote for this item by this user in the votes table.
|
28
52
|
def vote_down(voteable)
|
29
|
-
votes.create(voteable
|
53
|
+
votes.create(:voteable => voteable, :value => -ALLOWED_VALUE)
|
30
54
|
end
|
31
55
|
|
56
|
+
# To allow the user to dynamically cast a vote, call <tt>cast_vote</tt> with the item
|
57
|
+
# to vote for and the value (1 or -1)
|
58
|
+
#
|
59
|
+
# user.cast_vote(item, 1)
|
60
|
+
#
|
61
|
+
# This will add a new record with a positive vote.
|
32
62
|
def cast_vote(voteable, value)
|
33
|
-
votes.create(voteable
|
63
|
+
votes.create(:voteable => voteable, :value => value)
|
34
64
|
end
|
35
65
|
end
|
36
66
|
end
|
data/lib/ibham/version.rb
CHANGED
data/lib/models/vote.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
class Vote < ActiveRecord::Base
|
2
|
+
|
3
|
+
ALLOWED_VALUE = 1
|
4
|
+
|
2
5
|
attr_accessible :value, :voteable
|
3
6
|
|
4
|
-
belongs_to :voteable, polymorphic
|
5
|
-
belongs_to :voter, polymorphic
|
7
|
+
belongs_to :voteable, :polymorphic => true
|
8
|
+
belongs_to :voter, :polymorphic => true
|
6
9
|
|
7
|
-
validates_uniqueness_of :voteable_id, scope
|
8
|
-
validates :value, inclusion
|
10
|
+
validates_uniqueness_of :voteable_id, :scope => :voter_id
|
11
|
+
validates :value, :inclusion => { :in => [ALLOWED_VALUE, -ALLOWED_VALUE], :message => "should be either #{ALLOWED_VALUE} or -#{ALLOWED_VALUE}" }
|
9
12
|
end
|
data/spec/models/vote_spec.rb
CHANGED
@@ -1,22 +1,22 @@
|
|
1
1
|
require_relative '../spec_helper'
|
2
2
|
|
3
3
|
describe Vote do
|
4
|
-
let(:user) { User.create!
|
5
|
-
let(:item) { Item.create!
|
4
|
+
let(:user) { User.create! }
|
5
|
+
let(:item) { Item.create! }
|
6
6
|
|
7
7
|
describe 'Validations' do
|
8
8
|
it 'should be valid if the value is 1' do
|
9
|
-
vote = Vote.new(value
|
9
|
+
vote = Vote.new(:value => 1)
|
10
10
|
vote.valid?.must_equal true
|
11
11
|
end
|
12
12
|
|
13
13
|
it 'should be valid if the value is -1' do
|
14
|
-
vote = Vote.new(value
|
14
|
+
vote = Vote.new(:value => -1)
|
15
15
|
vote.valid?.must_equal true
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'should fail if the value is other than 1 or -1' do
|
19
|
-
vote = Vote.new(value
|
19
|
+
vote = Vote.new(:value => 2)
|
20
20
|
vote.valid?.must_equal false
|
21
21
|
vote.errors.full_messages.must_include 'Value should be either 1 or -1'
|
22
22
|
end
|
@@ -28,13 +28,13 @@ describe 'ActsAsVoteable' do
|
|
28
28
|
|
29
29
|
describe '#up_percentage' do
|
30
30
|
it 'should return the percentage of positive votes' do
|
31
|
-
item.up_percentage.
|
31
|
+
item.up_percentage.must_equal 67
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
35
|
describe '#down_percentage' do
|
36
36
|
it 'should return the percentage of negative votes' do
|
37
|
-
item.down_percentage.
|
37
|
+
item.down_percentage.must_equal 33
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'should return 100% if the item has 1 negative vote' do
|
@@ -45,4 +45,25 @@ describe 'ActsAsVoteable' do
|
|
45
45
|
item2.up_percentage.must_equal 0
|
46
46
|
end
|
47
47
|
end
|
48
|
+
|
49
|
+
describe '#voters' do
|
50
|
+
it 'should return the list of voters' do
|
51
|
+
item.voters.sort.must_equal [user2, user1, user3].sort
|
52
|
+
item2.voters.must_equal [user1]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#up_voters' do
|
57
|
+
it 'should return the list of users who casted positive votes' do
|
58
|
+
item.up_voters.sort.must_equal [user1, user3].sort
|
59
|
+
item2.up_voters.must_equal []
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '#down_voters' do
|
64
|
+
it 'should return the list of users who casted negative votes' do
|
65
|
+
item.down_voters.sort.must_equal [user2]
|
66
|
+
item2.down_voters.must_equal [user1]
|
67
|
+
end
|
68
|
+
end
|
48
69
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require_relative '../spec_helper'
|
2
2
|
|
3
3
|
describe 'ActsAsVoter' do
|
4
|
-
let(:user) { User.create!
|
5
|
-
let(:item) { Item.create!
|
4
|
+
let(:user) { User.create! }
|
5
|
+
let(:item) { Item.create! }
|
6
6
|
|
7
7
|
describe '#can_vote_for?' do
|
8
8
|
it 'should return true if the voter can vote for an item' do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'active_record'
|
2
|
-
require 'database_cleaner'
|
3
2
|
require 'sqlite3'
|
4
3
|
require 'ibham'
|
5
4
|
require 'minitest/autorun'
|
@@ -9,19 +8,29 @@ db_config = {
|
|
9
8
|
:database => ':memory:'
|
10
9
|
}
|
11
10
|
|
12
|
-
ActiveRecord::Base.establish_connection(db_config)
|
13
|
-
|
14
11
|
ActiveRecord::Migration.verbose = false
|
15
12
|
|
16
13
|
class MiniTest::Spec
|
17
|
-
before
|
18
|
-
|
14
|
+
before do
|
15
|
+
User.destroy_all
|
16
|
+
Item.destroy_all
|
17
|
+
Vote.destroy_all
|
18
|
+
end
|
19
|
+
|
20
|
+
config = {
|
21
|
+
:adapter => 'sqlite3',
|
22
|
+
:database => ':memory:'
|
23
|
+
}
|
24
|
+
|
25
|
+
ActiveRecord::Base.establish_connection(config)
|
26
|
+
ActiveRecord::Base.connection.create_database config[:database] rescue nil
|
27
|
+
ActiveRecord::Base.connection.drop_database config[:database] rescue nil
|
19
28
|
end
|
20
29
|
|
21
30
|
ActiveRecord::Schema.define do
|
22
31
|
create_table :votes do |t|
|
23
|
-
t.references :voter, polymorphic
|
24
|
-
t.references :voteable, polymorphic
|
32
|
+
t.references :voter, :polymorphic => true
|
33
|
+
t.references :voteable, :polymorphic => true
|
25
34
|
t.integer :value
|
26
35
|
|
27
36
|
t.timestamps
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ibham
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-10-
|
12
|
+
date: 2012-10-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
16
|
-
requirement: &
|
16
|
+
requirement: &70249569608880 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70249569608880
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &70249569608460 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,21 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
name: database_cleaner
|
38
|
-
requirement: &70361593617980 !ruby/object:Gem::Requirement
|
39
|
-
none: false
|
40
|
-
requirements:
|
41
|
-
- - ! '>='
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
version: '0'
|
44
|
-
type: :development
|
45
|
-
prerelease: false
|
46
|
-
version_requirements: *70361593617980
|
35
|
+
version_requirements: *70249569608460
|
47
36
|
- !ruby/object:Gem::Dependency
|
48
37
|
name: sqlite3
|
49
|
-
requirement: &
|
38
|
+
requirement: &70249569608040 !ruby/object:Gem::Requirement
|
50
39
|
none: false
|
51
40
|
requirements:
|
52
41
|
- - ! '>='
|
@@ -54,7 +43,7 @@ dependencies:
|
|
54
43
|
version: '0'
|
55
44
|
type: :development
|
56
45
|
prerelease: false
|
57
|
-
version_requirements: *
|
46
|
+
version_requirements: *70249569608040
|
58
47
|
description: Voting System for Rails applications
|
59
48
|
email:
|
60
49
|
- jamal@elmilahi.com
|
@@ -111,3 +100,4 @@ test_files:
|
|
111
100
|
- spec/modules/acts_as_voteable_spec.rb
|
112
101
|
- spec/modules/acts_as_voter_spec.rb
|
113
102
|
- spec/spec_helper.rb
|
103
|
+
has_rdoc:
|