Skip to content

Commit

Permalink
Huge updates:
Browse files Browse the repository at this point in the history
- Renamed to ThumbsUp.
- (Almost) all code updated for Rails 3 using AR/Arel.
- Removed a bunch of extra junk.
  • Loading branch information
Brady Bouchard committed Aug 3, 2010
1 parent b15dece commit 5fd4901
Show file tree
Hide file tree
Showing 27 changed files with 288 additions and 864 deletions.
1 change: 0 additions & 1 deletion .gitignore

This file was deleted.

7 changes: 7 additions & 0 deletions CHANGELOG.markdown
@@ -1,3 +1,10 @@
2010-08-03
==========
* Renamed to ThumbsUp from vote\_fu.
* Updated for Rails 3, using ActiveRecord/Arel.
* 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).
* Removed some shitty example code - this gem is self-explanatory and straight-forward as-is.

2010-02-04
==========
* Remove vote.rb and votes_controller.rb from gem lib
Expand Down
23 changes: 23 additions & 0 deletions MIT-LICENSE
@@ -1,3 +1,26 @@
Copyright (c) 2010 Brady Bouchard (ldawn.com)

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Major portions of this package were adapted from VoteFu, which is subject to the same license. Here is the original copyright notice for VoteFu:

Copyright (c) 2008 Peter Jackson (peteonrails.com)

Permission is hereby granted, free of charge, to any person obtaining
Expand Down
151 changes: 25 additions & 126 deletions README.markdown
@@ -1,64 +1,42 @@
vote_fu
ThumbsUp
=======

Allows an arbitrary number of entites (including Users) to vote on models.
Allows an arbitrary number of entities (users, etc.) to vote on models.

### Mixins
This plugin introduces three mixins to your recipe book:
This plugin introduces two mixins to your recipe book:

1. **acts\_as\_voteable** : Intended for content objects like Posts, Comments, etc.
2. **acts\_as\_voter** : Intended for voting entities, like Users.
3. **has\_karma** : Intended for voting entities, or other objects that own the things you're voting on.

### Inspiration

This plugin started as an adaptation / update of act\_as\_voteable. It has grown different from that plugin in several ways:

1. You can specify the model name that initiates votes.
2. You can, with a little tuning, have more than one entity type vote on more than one model type.
3. Adds "acts\_as\_voter" behavior to the initiator of votes.
4. Introduces some newer Rails features like named\_scope and :polymorphic keywords
5. Adds "has\_karma" mixin for identifying key content contributors

### Difference between original vote_fu and our gem

Generator creates model vote.rb in you application instead of keeping it in the gem lib.
We had bad experience with extending this class in application - unexpected things where having place.
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.

Installation
============
Use either the plugin or the gem installation method depending on your preference. If you're not sure, the plugin method is simpler. Whichever you choose, create the migration afterward and run it to create the required model.

### Via plugin
./script/plugin install git://github.com/objectreload/vote_fu.git
### Require the gem:

### Via gem
Add the following to your application's environment.rb:
config.gem "objectreload-vote_fu", :lib => 'vote_fu'
gem 'thumbs_up'

Install the gem:
rake gems:install
### Create and run the ThumbsUp migration:

### Create vote_fu migration and vote.rb model
./script/generate vote_fu

Run the migration:
rails generate thumbs_up
rake db:migrate

Usage
=====

## Getting Started

### Make your ActiveRecord model act as voteable.

### Turn your AR model into something that can be voted upon.

class Model < ActiveRecord::Base
acts_as_voteable
end


### Make your ActiveRecord model(s) that vote act as voter.
### Turn your Users (or any other model) into voters.

class User < ActiveRecord::Base
acts_as_voter
Expand All @@ -71,19 +49,16 @@ Usage
### To cast a vote for a Model you can do the following:

#### Shorthand syntax
voter.vote_for(voteable) # Adds a +1 vote
voter.vote_against(voteable) # Adds a -1 vote
voter.vote(voteable, t_or_f) # Adds either +1 or -1 vote true => +1, false => -1
voter.vote_for(voteable) # Adds a +1 vote
voter.vote_against(voteable) # Adds a -1 vote
voter.vote(voteable, vote) # Adds either a +1 or -1 vote: vote => true (+1), vote => false (-1)

#### ActsAsVoteable syntax
The old acts\_as\_voteable syntax is still supported:
### Querying votes

vote = Vote.new(:vote => true)
m = Model.find(params[:id])
m.votes << vote
user.votes << vote
Did the first user vote for the Car with id = 2 already?

### Querying votes
u = User.first
u.voted_on?(Car.find(2))

#### Tallying Votes

Expand All @@ -95,7 +70,7 @@ You can easily retrieve voteable object collections based on the properties of t
:start_at => 2.weeks.ago,
:end_at => 1.day.ago,
:limit => 10,
:order => "items.name desc"
:order => "items.name DESC"
})

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.
Expand Down Expand Up @@ -123,102 +98,26 @@ And because the Vote Fu plugin will add the has_many votes relationship to your
The mixin also provides these methods:

voter.voted_for?(voteable) # True if the voter voted for this object.
voter.vote_count([true|false|"all"]) # returns the count of +1, -1, or all votes
voter.vote_count(:up | :down | :all) # returns the count of +1, -1, or all votes

voteable.voted_by?(voter) # True if the voter voted for this object.
@voters = voteable.voters_who_voted


#### Named Scopes

The Vote model has several named scopes you can use to find vote details:

@pete_votes = Vote.for_voter(pete)
@post_votes = Vote.for_voteable(post)
@recent_votes = Vote.recent(1.day.ago)
@descending_votes = Vote.descending

You can chain these together to make interesting queries:

# Show all of Pete's recent votes for a certain Post, in descending order (newest first)
@pete_recent_votes_on_post = Vote.for_voter(pete).for_voteable(post).recent(7.days.ago).descending

### Experimental: Voteable Object Owner Karma
I have just introduced the "has\_karma" mixin to this package. It aims to assign a karma score to the owners of voteable objects. This is designed to allow you to see which users are submitting the most highly voted content. Currently, karma is only "positive". That is, +1 votes add to karma, but -1 votes do not detract from it.

class User
has_many :posts
has_karma :posts
end

class Post
acts_as_voteable
end

# in your view, you can then do this:
Karma: <%= @user.karma %>

This feature is in alpha, but useful enough that I'm releasing it.

### One vote per user!
If you want to limit your users to a single vote on each item, take a look in lib/vote.rb.

# Uncomment this to limit users to a single vote on each item.
# validates_uniqueness_of :voteable_id, :scope => [:voteable_type, :voter_type, :voter_id]

And if you want that enforced at the database level, look in the generated migration for your voteable:

# If you want to enfore "One Person, One Vote" rules in the database, uncomment the index below
# add_index :votes, ["voter_id", "voter_type", "voteable_id", "voteable_type"], :unique => true, :name => "uniq_one_vote_only"

### Example Application
ThumbsUp by default only allows one vote per user. This can be changed by removing:

There is now a reference application available. Due to overwhelming demand for example
code and kickstart guides, I have open-sourced MyQuotable.com in order to provide an
easy-to-follow example of how to use VoteFu with RESTful Authentication, JRails, and
other popular plugins. To get the example code:
#### In vote.rb:

git clone git://github.com/peteonrails/myquotable.git
validates_uniqueness_of :voteable_id, :scope => [:voteable_type, :voter_type, :voter_id]

There will be a screencast coming soon too. Contact me if you want to help.
#### In the migration:

Consideration
=============
If you like this software and use it, please consider recommending me on Working With Rails.

I don't want donations: a simple up-vote would make my day. My profile is: [http://www.workingwithrails.com/person/12521-peter-jackson][4]

To go directly to the "Recommend Me" screen: [http://www.workingwithrails.com/recommendation/new/person/12521-peter-jackson][5]
add_index :votes, ["voter_id", "voter_type", "voteable_id", "voteable_type"], :unique => true, :name => "uniq_one_vote_only"


Credits
=======

#### Contributors

* Bence Nagy, Budapest, Hungary
* Jon Maddox, Richmond, Virginia, USA

#### Other works

[Juixe - The original ActsAsVoteable plugin inspired this code.][1]

[Xelipe - This plugin is heavily influenced by Acts As Commentable.][2]

[1]: http://www.juixe.com/techknow/index.php/2006/06/24/acts-as-voteable-rails-plugin/
[2]: http://github.com/jackdempsey/acts_as_commentable/tree/master

More
====

Support: [Use my blog for support.][6]


[Documentation from the original acts\_as\_voteable plugin][3]

[3]: http://www.juixe.com/techknow/index.php/2006/06/24/acts-as-voteable-rails-plugin/
[4]: http://www.workingwithrails.com/person/12521-peter-jackson
[5]: http://www.workingwithrails.com/recommendation/new/person/12521-peter-jackson
[6]: http://blog.peteonrails.com

Copyright (c) 2008 Peter Jackson, released under the MIT license
Basic structure and a good chunk of code is taken from Peter Jackson's work on ActsAsVoteable.
48 changes: 5 additions & 43 deletions Rakefile
Expand Up @@ -5,53 +5,15 @@ require 'rake'
begin
require 'jeweler'
Jeweler::Tasks.new do |gem|
gem.name = "objectreload-vote_fu"
gem.name = "thumbs_up"
gem.summary = "Voting for ActiveRecord with multiple vote sources and advanced features."
gem.description = "VoteFu provides the ability to have multiple voting entities on an arbitrary number of models in ActiveRecord."
gem.email = "gems@objectreload.com"
gem.homepage = "http://github.com/objectreload/vote_fu"
gem.authors = ["Peter Jackson", "Cosmin Radoi", "Bence Nagy", "Rob Maddox", "Wojciech Wnętrzak"]
gem.description = "ThumbsUp provides the ability to have multiple voting entities on an arbitrary number of models in ActiveRecord."
gem.email = "brady@ldawn.com"
gem.homepage = "http://github.com/brady8/thumbs_up"
gem.authors = ["Peter Jackson", "Cosmin Radoi", "Bence Nagy", "Rob Maddox", "Wojciech Wnętrzak", "Brady Bouchard"]
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
end
Jeweler::GemcutterTasks.new
rescue LoadError
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
end

require 'rake/testtask'
Rake::TestTask.new(:test) do |test|
test.libs << 'lib' << 'test'
test.pattern = 'test/**/*_test.rb'
test.verbose = true
end

begin
require 'rcov/rcovtask'
Rcov::RcovTask.new do |test|
test.libs << 'test'
test.pattern = 'test/**/*_test.rb'
test.verbose = true
end
rescue LoadError
task :rcov do
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
end
end

task :test => :check_dependencies

task :default => :test

require 'rake/rdoctask'
Rake::RDocTask.new do |rdoc|
if File.exist?('VERSION')
version = File.read('VERSION')
else
version = ""
end

rdoc.rdoc_dir = 'rdoc'
rdoc.title = "permissions_gem #{version}"
rdoc.rdoc_files.include('README*')
rdoc.rdoc_files.include('lib/**/*.rb')
end
2 changes: 1 addition & 1 deletion VERSION
@@ -1 +1 @@
0.1.2
0.2.0
7 changes: 0 additions & 7 deletions examples/routes.rb

This file was deleted.

0 comments on commit 5fd4901

Please sign in to comment.