ibham 0.1.1 → 0.1.2
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/.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:
|