thumbs_up 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ 2010-08-03
2
+ ==========
3
+ * Renamed to ThumbsUp from vote\_fu.
4
+ * Updated for Rails 3, using ActiveRecord/Arel.
5
+ * Cleaned up some dead code, some shitty code, and made a few methods take up quite a lot less memory and time (voters\_who\_voted).
6
+ * Removed some shitty example code - this gem is self-explanatory and straight-forward as-is.
7
+ * Fixed karma.
data/MIT-LICENSE ADDED
@@ -0,0 +1,66 @@
1
+ Copyright (c) 2010 Brady Bouchard (ldawn.com)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ Major portions of this package were adapted from VoteFu, which is subject to the same license. Here is the original copyright notice for VoteFu:
23
+
24
+ Copyright (c) 2008 Peter Jackson (peteonrails.com)
25
+
26
+ Permission is hereby granted, free of charge, to any person obtaining
27
+ a copy of this software and associated documentation files (the
28
+ "Software"), to deal in the Software without restriction, including
29
+ without limitation the rights to use, copy, modify, merge, publish,
30
+ distribute, sublicense, and/or sell copies of the Software, and to
31
+ permit persons to whom the Software is furnished to do so, subject to
32
+ the following conditions:
33
+
34
+ The above copyright notice and this permission notice shall be
35
+ included in all copies or substantial portions of the Software.
36
+
37
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
38
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
39
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
40
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
41
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
42
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
43
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
44
+
45
+ Major portions of this package were adapted from ActsAsVoteable, which is subject to the same license. Here is the original copyright notice for ActsAsVoteable:
46
+
47
+ Copyright (c) 2006 Cosmin Radoi
48
+
49
+ Permission is hereby granted, free of charge, to any person obtaining
50
+ a copy of this software and associated documentation files (the
51
+ "Software"), to deal in the Software without restriction, including
52
+ without limitation the rights to use, copy, modify, merge, publish,
53
+ distribute, sublicense, and/or sell copies of the Software, and to
54
+ permit persons to whom the Software is furnished to do so, subject to
55
+ the following conditions:
56
+
57
+ The above copyright notice and this permission notice shall be
58
+ included in all copies or substantial portions of the Software.
59
+
60
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
61
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
62
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
63
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
64
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
65
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
66
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,126 @@
1
+ ThumbsUp
2
+ =======
3
+
4
+ A ridiculously straightforward and simple package 'o' code to enable voting in your application, a la stackoverflow.com, etc.
5
+ Allows an arbitrary number of entities (users, etc.) to vote on models.
6
+
7
+ ### Mixins
8
+ This plugin introduces two mixins to your recipe book:
9
+
10
+ 1. **acts\_as\_voteable** : Intended for content objects like Posts, Comments, etc.
11
+ 2. **acts\_as\_voter** : Intended for voting entities, like Users.
12
+ 3. **has\_karma** : Adds some helpers to acts\_as\_voter models for calculating karma.
13
+
14
+ ### Inspiration
15
+
16
+ This plugin started as an adaptation / update of vote\_fu for use with Rails 3. It adds some speed, removes some cruft, and is adapted for use with ActiveRecord / Arel in Rails 3. It maintains the awesomeness of the original vote\_fu.
17
+
18
+ Installation
19
+ ============
20
+
21
+ ### Require the gem:
22
+
23
+ gem 'thumbs_up'
24
+
25
+ ### Create and run the ThumbsUp migration:
26
+
27
+ rails generate thumbs_up
28
+ rake db:migrate
29
+
30
+ Usage
31
+ =====
32
+
33
+ ## Getting Started
34
+
35
+ ### Turn your AR models into something that can be voted upon.
36
+
37
+ class SomeModel < ActiveRecord::Base
38
+ acts_as_voteable
39
+ end
40
+
41
+ class Question < ActiveRecord::Base
42
+ acts_as_voteable
43
+ end
44
+
45
+ ### Turn your Users (or any other model) into voters.
46
+
47
+ class User < ActiveRecord::Base
48
+ acts_as_voter
49
+ # The following line is optional, and tracks karma (up votes) for questions this user has submitted.
50
+ # Each question has a submitter_id column that tracks the user who submitted it.
51
+ # You can track any voteable model.
52
+ has_karma(:questions, :as => :submitter)
53
+ end
54
+
55
+ class Robot < ActiveRecord::Base
56
+ acts_as_voter
57
+ end
58
+
59
+ ### To cast a vote for a Model you can do the following:
60
+
61
+ #### Shorthand syntax
62
+ voter.vote_for(voteable) # Adds a +1 vote
63
+ voter.vote_against(voteable) # Adds a -1 vote
64
+ voter.vote(voteable, vote) # Adds either a +1 or -1 vote: vote => true (+1), vote => false (-1)
65
+
66
+ ### Querying votes
67
+
68
+ Did the first user vote for the Car with id = 2 already?
69
+
70
+ u = User.first
71
+ u.voted_on?(Car.find(2))
72
+
73
+ #### Tallying Votes
74
+
75
+ You can easily retrieve voteable object collections based on the properties of their votes:
76
+
77
+ @items = Item.tally(
78
+ { :at_least => 1,
79
+ :at_most => 10000,
80
+ :start_at => 2.weeks.ago,
81
+ :end_at => 1.day.ago,
82
+ :limit => 10,
83
+ :order => "items.name DESC"
84
+ })
85
+
86
+ This will select the Items with between 1 and 10,000 votes, the votes having been cast within the last two weeks (not including today), then display the 10 last items in an alphabetical list.
87
+
88
+ ##### Tally Options:
89
+ :start_at - Restrict the votes to those created after a certain time
90
+ :end_at - Restrict the votes to those created before a certain time
91
+ :conditions - A piece of SQL conditions to add to the query
92
+ :limit - The maximum number of voteables to return
93
+ :order - A piece of SQL to order by. Eg 'votes.count desc' or 'voteable.created_at desc'
94
+ :at_least - Item must have at least X votes
95
+ :at_most - Item may not have more than X votes
96
+
97
+ #### Lower level queries
98
+
99
+ positiveVoteCount = voteable.votes_for
100
+ negativeVoteCount = voteable.votes_against
101
+ plusminus = voteable.plusminus # Votes for minus votes against.
102
+
103
+ voter.voted_for?(voteable) # True if the voter voted for this object.
104
+ voter.vote_count(:up | :down | :all) # returns the count of +1, -1, or all votes
105
+
106
+ voteable.voted_by?(voter) # True if the voter voted for this object.
107
+ @voters = voteable.voters_who_voted
108
+
109
+
110
+ ### One vote per user!
111
+
112
+ ThumbsUp by default only allows one vote per user. This can be changed by removing:
113
+
114
+ #### In vote.rb:
115
+
116
+ validates_uniqueness_of :voteable_id, :scope => [:voteable_type, :voter_type, :voter_id]
117
+
118
+ #### In the migration:
119
+
120
+ add_index :votes, ["voter_id", "voter_type", "voteable_id", "voteable_type"], :unique => true, :name => "uniq_one_vote_only"
121
+
122
+
123
+ Credits
124
+ =======
125
+
126
+ Basic scaffold is from Peter Jackson's work on VoteFu / ActsAsVoteable. All code updated for Rails 3, cleaned up for speed and clarity, karma calculation fixed, and (hopefully) zero introduced bugs.
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ # encoding: UTF-8
2
+ require 'rubygems'
3
+ require 'rake'
4
+
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |gem|
8
+ gem.name = "thumbs_up"
9
+ gem.summary = "Voting for ActiveRecord with multiple vote sources and karma calculation."
10
+ gem.description = "ThumbsUp provides dead-simple voting capabilities to ActiveRecord models with karma calculation, a la stackoverflow.com."
11
+ gem.email = "brady@ldawn.com"
12
+ gem.homepage = "http://github.com/brady8/thumbs_up"
13
+ gem.authors = ["Brady Bouchard", "Peter Jackson", "Cosmin Radoi", "Bence Nagy", "Rob Maddox", "Wojciech Wnętrzak"]
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.1
@@ -0,0 +1,85 @@
1
+ module ThumbsUp
2
+ module ActsAsVoteable #:nodoc:
3
+
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ end
7
+
8
+ module ClassMethods
9
+ def acts_as_voteable
10
+ has_many :votes, :as => :voteable, :dependent => :nullify
11
+
12
+ include ThumbsUp::ActsAsVoteable::InstanceMethods
13
+ extend ThumbsUp::ActsAsVoteable::SingletonMethods
14
+ end
15
+ end
16
+
17
+ module SingletonMethods
18
+
19
+ # Calculate the vote counts for all voteables of my type.
20
+ # This method returns all voteables with at least one vote.
21
+ # The vote count for each voteable is available as #vote_count.
22
+ #
23
+ # Options:
24
+ # :start_at - Restrict the votes to those created after a certain time
25
+ # :end_at - Restrict the votes to those created before a certain time
26
+ # :conditions - A piece of SQL conditions to add to the query
27
+ # :limit - The maximum number of voteables to return
28
+ # :order - A piece of SQL to order by. Eg 'vote_count DESC' or 'voteable.created_at DESC'
29
+ # :at_least - Item must have at least X votes
30
+ # :at_most - Item may not have more than X votes
31
+ def tally(*args)
32
+ options = args.extract_options!
33
+ t = self.where("#{Vote.table_name}.voteable_type = '#{self.name}'")
34
+ # We join so that you can order by columns on the voteable model.
35
+ t = t.joins("LEFT OUTER JOIN #{Vote.table_name} ON #{self.table_name}.#{self.primary_key} = #{Vote.table_name}.voteable_id")
36
+ t = t.having("vote_count > 0")
37
+ t = t.group("#{Vote.table_name}.voteable_id")
38
+ t = t.limit(options[:limit]) if options[:limit]
39
+ t = t.where("#{Vote.table_name}.created_at >= ?", options[:start_at]) if options[:start_at]
40
+ t = t.where("#{Vote.table_name}.created_at <= ?", options[:end_at]) if options[:end_at]
41
+ t = t.where(options[:conditions]) if options[:conditions]
42
+ t = options[:order] ? t.order(options[:order]) : t.order("vote_count DESC")
43
+ t = t.having(["vote_count >= ?", options[:at_least]]) if options[:at_least]
44
+ t = t.having(["vote_count <= ?", options[:at_most]]) if options[:at_most]
45
+ t.select("#{self.table_name}.*, COUNT(#{Vote.table_name}.voteable_id) AS vote_count")
46
+ end
47
+
48
+ end
49
+
50
+ module InstanceMethods
51
+
52
+ def votes_for
53
+ Vote.where(:voteable_id => id, :voteable_type => self.class.name, :vote => true).count
54
+ end
55
+
56
+ def votes_against
57
+ Vote.where(:voteable_id => id, :voteable_type => self.class.name, :vote => false).count
58
+ end
59
+
60
+ # You'll probably want to use this method to display how 'good' a particular voteable
61
+ # is, and/or sort based on it.
62
+ def plusminus
63
+ votes_for - votes_against
64
+ end
65
+
66
+ def votes_count
67
+ self.votes.size
68
+ end
69
+
70
+ def voters_who_voted
71
+ self.votes.map(&:voter).uniq
72
+ end
73
+
74
+ def voted_by?(voter)
75
+ 0 < Vote.where(
76
+ :voteable_id => self.id,
77
+ :voteable_type => self.class.name,
78
+ :voter_type => voter.class.name,
79
+ :voter_id => voter.id
80
+ ).count
81
+ end
82
+
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,84 @@
1
+ module ThumbsUp #:nodoc:
2
+ module ActsAsVoter #:nodoc:
3
+
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ end
7
+
8
+ module ClassMethods
9
+ def acts_as_voter
10
+
11
+ # If a voting entity is deleted, keep the votes.
12
+ # has_many :votes, :as => :voter, :dependent => :nullify
13
+ # Destroy votes when a user is deleted.
14
+ has_many :votes, :as => :voter, :dependent => :destroy
15
+
16
+ include ThumbsUp::ActsAsVoter::InstanceMethods
17
+ extend ThumbsUp::ActsAsVoter::SingletonMethods
18
+ end
19
+ end
20
+
21
+ # This module contains class methods
22
+ module SingletonMethods
23
+ end
24
+
25
+ # This module contains instance methods
26
+ module InstanceMethods
27
+
28
+ # Usage user.vote_count(:up) # All +1 votes
29
+ # user.vote_count(:down) # All -1 votes
30
+ # user.vote_count() # All votes
31
+
32
+ def vote_count(for_or_against = :all)
33
+ v = Vote.where(:voter_id => id).where(:voter_type => self.class.name)
34
+ v = case for_or_against
35
+ when :all then v
36
+ when :up then v.where(:vote => true)
37
+ when :down then v.where(:vote => false)
38
+ end
39
+ v.count
40
+ end
41
+
42
+ def voted_for?(voteable)
43
+ voted_which_way?(voteable, :up)
44
+ end
45
+
46
+ def voted_against?(voteable)
47
+ voted_which_way?(voteable, :down)
48
+ end
49
+
50
+ def voted_on?(voteable)
51
+ 0 < Vote.where(
52
+ :voter_id => self.id,
53
+ :voter_type => self.class.name,
54
+ :voteable_id => voteable.id,
55
+ :voteable_type => voteable.class.name
56
+ ).count
57
+ end
58
+
59
+ def vote_for(voteable)
60
+ self.vote(voteable, true)
61
+ end
62
+
63
+ def vote_against(voteable)
64
+ self.vote(voteable, false)
65
+ end
66
+
67
+ def vote(voteable, vote)
68
+ Vote.create!(:vote => vote, :voteable => voteable, :voter => self)
69
+ end
70
+
71
+ def voted_which_way?(voteable, direction)
72
+ raise ArgumentError, "expected :up or :down" unless [:up, :down].include?(direction)
73
+ 0 < Vote.where(
74
+ :voter_id => self.id,
75
+ :voter_type => self.class.name,
76
+ :vote => direction == :up ? true : false,
77
+ :voteable_id => voteable.id,
78
+ :voteable_type => voteable.class.name
79
+ ).count
80
+ end
81
+
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,21 @@
1
+ class ThumbsUpMigration < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :votes, :force => true do |t|
4
+ t.boolean :vote, :default => false
5
+ t.references :voteable, :polymorphic => true, :null => false
6
+ t.references :voter, :polymorphic => true
7
+ t.timestamps
8
+ end
9
+
10
+ add_index :votes, ["voter_id", "voter_type"], :name => "fk_voters"
11
+ add_index :votes, ["voteable_id", "voteable_type"], :name => "fk_voteables"
12
+
13
+ # If you don't want to enforce "One Person, One Vote" rules in the database, comment out the index below.
14
+ add_index :votes, ["voter_id", "voter_type", "voteable_id", "voteable_type"], :unique => true, :name => "uniq_one_vote_only"
15
+ end
16
+
17
+ def self.down
18
+ drop_table :votes
19
+ end
20
+
21
+ end
@@ -0,0 +1,16 @@
1
+ class Vote < ActiveRecord::Base
2
+
3
+ scope :for_voter, lambda { |*args| where(["voter_id = ? AND voter_type = ?", args.first.id, args.first.class.name]) }
4
+ scope :for_voteable, lambda { |*args| where(["voteable_id = ? AND voteable_type = ?", args.first.id, args.first.class.name]) }
5
+ scope :recent, lambda { |*args| where(["created_at > ?", (args.first || 2.weeks.ago)]) }
6
+ scope :descending, order("created_at DESC")
7
+
8
+ belongs_to :voteable, :polymorphic => true
9
+ belongs_to :voter, :polymorphic => true
10
+
11
+ attr_accessible :vote, :voter, :voteable
12
+
13
+ # Comment out the line below to allow multiple votes per user.
14
+ validates_uniqueness_of :voteable_id, :scope => [:voteable_type, :voter_type, :voter_id]
15
+
16
+ end
@@ -0,0 +1,27 @@
1
+ require 'rails/generators/active_record'
2
+
3
+ class ThumbsUpGenerator < Rails::Generators::Base
4
+
5
+ include Rails::Generators::Migration
6
+
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ # Implement the required interface for Rails::Generators::Migration.
10
+ def self.next_migration_number(dirname) #:nodoc:
11
+ next_migration_number = current_migration_number(dirname) + 1
12
+ if ActiveRecord::Base.timestamped_migrations
13
+ [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % next_migration_number].max
14
+ else
15
+ "%.3d" % next_migration_number
16
+ end
17
+ end
18
+
19
+ def create_migration
20
+ migration_template 'migration.rb', File.join('db', 'migrate', 'thumbs_up_migration.rb')
21
+ end
22
+
23
+ def move_vote_model
24
+ template 'vote.rb', File.join('app', 'models', 'vote.rb')
25
+ end
26
+
27
+ end
data/lib/has_karma.rb ADDED
@@ -0,0 +1,42 @@
1
+ module ThumbsUp #:nodoc:
2
+ module Karma #:nodoc:
3
+
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ class << base
7
+ attr_accessor :karmic_objects
8
+ end
9
+ end
10
+
11
+ module ClassMethods
12
+ def has_karma(voteable_type, options = {})
13
+ include ThumbsUp::Karma::InstanceMethods
14
+ extend ThumbsUp::Karma::SingletonMethods
15
+ self.karmic_objects ||= {}
16
+ self.karmic_objects[voteable_type.to_s.classify.constantize] = (options[:as] ? options[:as].to_s.foreign_key : self.class.name.foreign_key)
17
+ end
18
+ end
19
+
20
+ module SingletonMethods
21
+
22
+ ## Not yet implemented. Don't use it!
23
+ # Find the most popular users
24
+ def find_most_karmic
25
+ find(:all)
26
+ end
27
+
28
+ end
29
+
30
+ module InstanceMethods
31
+ def karma(options = {})
32
+ self.class.karmic_objects.collect do |object, fk|
33
+ v = object.where(["#{Vote.table_name}.vote = ?", true]).where(["#{self.class.table_name}.#{self.class.primary_key} = ?", self.id])
34
+ v = v.joins("INNER JOIN #{Vote.table_name} ON #{Vote.table_name}.voteable_type = '#{object.to_s}' AND #{Vote.table_name}.voteable_id = #{object.table_name}.#{object.primary_key}")
35
+ v = v.joins("INNER JOIN #{self.class.table_name} ON #{self.class.table_name}.#{self.class.primary_key} = #{object.table_name}.#{fk}")
36
+ v.count
37
+ end.sum
38
+ end
39
+ end
40
+
41
+ end
42
+ end
data/lib/thumbs_up.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'acts_as_voteable'
2
+ require 'acts_as_voter'
3
+ require 'has_karma'
4
+
5
+ ActiveRecord::Base.send(:include, ThumbsUp::ActsAsVoteable)
6
+ ActiveRecord::Base.send(:include, ThumbsUp::ActsAsVoter)
7
+ ActiveRecord::Base.send(:include, ThumbsUp::Karma)
data/rails/init.rb ADDED
@@ -0,0 +1,10 @@
1
+ RAILS_DEFAULT_LOGGER.info "** thumbs_up: setting up load paths **"
2
+
3
+ %w{ models controllers helpers }.each do |dir|
4
+ path = File.join(File.dirname(__FILE__) , 'lib', dir)
5
+ $LOAD_PATH << path
6
+ ActiveSupport::Dependencies.load_paths << path
7
+ ActiveSupport::Dependencies.load_once_paths.delete(path)
8
+ end
9
+
10
+ require 'thumbs_up'
data/thumbs_up.gemspec ADDED
@@ -0,0 +1,50 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{thumbs_up}
8
+ s.version = "0.2.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Brady Bouchard", "Peter Jackson", "Cosmin Radoi", "Bence Nagy", "Rob Maddox", "Wojciech Wn\304\231trzak"]
12
+ s.date = %q{2010-08-04}
13
+ s.description = %q{ThumbsUp provides dead-simple voting capabilities to ActiveRecord models with karma calculation, a la stackoverflow.com.}
14
+ s.email = %q{brady@ldawn.com}
15
+ s.extra_rdoc_files = [
16
+ "README.markdown"
17
+ ]
18
+ s.files = [
19
+ "CHANGELOG.markdown",
20
+ "MIT-LICENSE",
21
+ "README.markdown",
22
+ "Rakefile",
23
+ "VERSION",
24
+ "lib/acts_as_voteable.rb",
25
+ "lib/acts_as_voter.rb",
26
+ "lib/generators/thumbs_up/templates/migration.rb",
27
+ "lib/generators/thumbs_up/templates/vote.rb",
28
+ "lib/generators/thumbs_up/thumbs_up_generator.rb",
29
+ "lib/has_karma.rb",
30
+ "lib/thumbs_up.rb",
31
+ "rails/init.rb",
32
+ "thumbs_up.gemspec"
33
+ ]
34
+ s.homepage = %q{http://github.com/brady8/thumbs_up}
35
+ s.rdoc_options = ["--charset=UTF-8"]
36
+ s.require_paths = ["lib"]
37
+ s.rubygems_version = %q{1.3.7}
38
+ s.summary = %q{Voting for ActiveRecord with multiple vote sources and karma calculation.}
39
+
40
+ if s.respond_to? :specification_version then
41
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
42
+ s.specification_version = 3
43
+
44
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
45
+ else
46
+ end
47
+ else
48
+ end
49
+ end
50
+
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: thumbs_up
3
+ version: !ruby/object:Gem::Version
4
+ hash: 21
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 2
9
+ - 1
10
+ version: 0.2.1
11
+ platform: ruby
12
+ authors:
13
+ - Brady Bouchard
14
+ - Peter Jackson
15
+ - Cosmin Radoi
16
+ - Bence Nagy
17
+ - Rob Maddox
18
+ - "Wojciech Wn\xC4\x99trzak"
19
+ autorequire:
20
+ bindir: bin
21
+ cert_chain: []
22
+
23
+ date: 2010-08-04 00:00:00 +10:00
24
+ default_executable:
25
+ dependencies: []
26
+
27
+ description: ThumbsUp provides dead-simple voting capabilities to ActiveRecord models with karma calculation, a la stackoverflow.com.
28
+ email: brady@ldawn.com
29
+ executables: []
30
+
31
+ extensions: []
32
+
33
+ extra_rdoc_files:
34
+ - README.markdown
35
+ files:
36
+ - CHANGELOG.markdown
37
+ - MIT-LICENSE
38
+ - README.markdown
39
+ - Rakefile
40
+ - VERSION
41
+ - lib/acts_as_voteable.rb
42
+ - lib/acts_as_voter.rb
43
+ - lib/generators/thumbs_up/templates/migration.rb
44
+ - lib/generators/thumbs_up/templates/vote.rb
45
+ - lib/generators/thumbs_up/thumbs_up_generator.rb
46
+ - lib/has_karma.rb
47
+ - lib/thumbs_up.rb
48
+ - rails/init.rb
49
+ - thumbs_up.gemspec
50
+ has_rdoc: true
51
+ homepage: http://github.com/brady8/thumbs_up
52
+ licenses: []
53
+
54
+ post_install_message:
55
+ rdoc_options:
56
+ - --charset=UTF-8
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ hash: 3
65
+ segments:
66
+ - 0
67
+ version: "0"
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ hash: 3
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ requirements: []
78
+
79
+ rubyforge_project:
80
+ rubygems_version: 1.3.7
81
+ signing_key:
82
+ specification_version: 3
83
+ summary: Voting for ActiveRecord with multiple vote sources and karma calculation.
84
+ test_files: []
85
+