README.markdown in acts_as_votable-0.10.0 vs README.markdown in acts_as_votable-0.11.0
- old
+ new
@@ -1,8 +1,9 @@
# Acts As Votable (aka Acts As Likeable)
[![Build Status](https://travis-ci.org/ryanto/acts_as_votable.png)](https://travis-ci.org/ryanto/acts_as_votable)
+[![Code Climate](https://codeclimate.com/github/ryanto/acts_as_votable.png)](https://codeclimate.com/github/ryanto/acts_as_votable)
Acts As Votable is a Ruby Gem specifically written for Rails/ActiveRecord models.
The main goals of this gem are:
- Allow any model to be voted on, like/dislike, upvote/downvote, etc.
@@ -13,18 +14,17 @@
## Installation
### Supported Ruby and Rails versions
-* Ruby 1.8.7, 1.9.2, 1.9.3
-* Ruby 2.0.0, 2.1.0
-* Rails 3.0, 3.1, 3.2
+* Ruby 2.2.0, 2.3.0 and 2.4.0
* Rails 4.0, 4.1+
+* Rails 5.0, 5.1
### Install
-Just add the following to your Gemfile.
+Just add the following to your Gemfile to install the latest release.
```ruby
gem 'acts_as_votable', '~> 0.10.0'
```
@@ -94,24 +94,26 @@
@post.downvote_from @user2
@post.vote_by :voter => @user2, :vote => 'bad'
# tally them up!
@post.votes_for.size # => 5
+@post.weighted_total => 5
@post.get_likes.size # => 3
@post.get_upvotes.size # => 3
@post.get_dislikes.size # => 2
@post.get_downvotes.size # => 2
+@post.weighted_score => 1
```
Active Record scopes are provided to make life easier.
```ruby
@post.votes_for.up.by_type(User)
@post.votes_for.down
@user1.votes.up
@user1.votes.down
-@user1.votes.up.by_type(Post)
+@user1.votes.up.for_type(Post)
```
Once scoping is complete, you can also trigger a get for the
voter/votable
@@ -135,11 +137,11 @@
Unvoting works for both positive and negative votes.
### Examples with scopes
-You can add an scope to your vote
+You can add a scope to your vote
```ruby
# positive votes
@post.liked_by @user1, :vote_scope => 'rank'
@post.vote_by :voter => @user3, :vote_scope => 'rank'
@@ -213,13 +215,13 @@
@user.voted_for? @comment1 # => true
@user.voted_for? @comment2 # => true
@user.voted_for? @comment3 # => false
-@user.voted_as_when_voted_for @comment1 # => true, he liked it
-@user.voted_as_when_voted_for @comment2 # => false, he didnt like it
-@user.voted_as_when_voted_for @comment3 # => nil, he has yet to vote
+@user.voted_as_when_voted_for @comment1 # => true, user liked it
+@user.voted_as_when_voted_for @comment2 # => false, user didnt like it
+@user.voted_as_when_voted_for @comment3 # => nil, user has yet to vote
```
You can also check whether the voter has voted up or down.
```ruby
@@ -315,16 +317,18 @@
add_column :posts, :cached_votes_score, :integer, :default => 0
add_column :posts, :cached_votes_up, :integer, :default => 0
add_column :posts, :cached_votes_down, :integer, :default => 0
add_column :posts, :cached_weighted_score, :integer, :default => 0
add_column :posts, :cached_weighted_total, :integer, :default => 0
+ add_column :posts, :cached_weighted_average, :float, :default => 0.0
add_index :posts, :cached_votes_total
add_index :posts, :cached_votes_score
add_index :posts, :cached_votes_up
add_index :posts, :cached_votes_down
add_index :posts, :cached_weighted_score
add_index :posts, :cached_weighted_total
+ add_index :posts, :cached_weighted_average
# Uncomment this line to force caching of existing votes
# Post.find_each(&:update_cached_votes)
end
@@ -333,14 +337,78 @@
remove_column :posts, :cached_votes_score
remove_column :posts, :cached_votes_up
remove_column :posts, :cached_votes_down
remove_column :posts, :cached_weighted_score
remove_column :posts, :cached_weighted_total
+ remove_column :posts, :cached_weighted_average
end
end
```
+If you have a scope for your vote, let's say `subscribe`, your migration will be slightly different like below:
+
+```ruby
+class AddCachedVotesToPosts < ActiveRecord::Migration
+ def self.up
+ add_column :posts, :cached_scoped_subscribe_votes_total, :integer, :default => 0
+ add_column :posts, :cached_scoped_subscribe_votes_score, :integer, :default => 0
+ add_column :posts, :cached_scoped_subscribe_votes_up, :integer, :default => 0
+ add_column :posts, :cached_scoped_subscribe_votes_down, :integer, :default => 0
+ add_column :posts, :cached_weighted_subscribe_score, :integer, :default => 0
+ add_column :posts, :cached_weighted_subscribe_total, :integer, :default => 0
+ add_column :posts, :cached_weighted_subscribe_average, :float, :default => 0.0
+ add_index :posts, :cached_scoped_subscribe_votes_total
+ add_index :posts, :cached_scoped_subscribe_votes_score
+ add_index :posts, :cached_scoped_subscribe_votes_up
+ add_index :posts, :cached_scoped_subscribe_votes_down
+ add_index :posts, :cached_weighted_subscribe_score
+ add_index :posts, :cached_weighted_subscribe_total
+ add_index :posts, :cached_weighted_subscribe_average
+ end
+
+ def self.down
+ remove_column :posts, :cached_scoped_subscribe_votes_total
+ remove_column :posts, :cached_scoped_subscribe_votes_score
+ remove_column :posts, :cached_scoped_subscribe_votes_up
+ remove_column :posts, :cached_scoped_subscribe_votes_down
+ remove_column :posts, :cached_weighted_subscribe_score
+ remove_column :posts, :cached_weighted_subscribe_total
+ remove_column :posts, :cached_weighted_subscribe_average
+ end
+end
+```
+
+`cached_weighted_average` can be helpful for a rating system, e.g.:
+
+Order by average rating:
+
+```ruby
+Post.order(:cached_weighted_average => :desc)
+```
+
+Display average rating:
+
+```erb
+<%= post.weighted_average.round(2) %> / 5
+<!-- 3.5 / 5 -->
+```
+## updated_at at Votable model
+
+You can control whether `updated_at` column of votable model will be touched or
+not by passing `cacheable_strategy` option to `acts_as_votable` method.
+
+By default, `update_attributes` strategy is used. Pass `:update_columns` as
+`cacheable_strategy` if you don't want to touch model's `updated_at` column.
+```ruby
+class Post < ActiveRecord::Base
+ acts_as_votable cacheable_strategy: :update_columns
+end
+```
+
+NOTE: this option does not work for ActiveRecord < 3.1
+
+
## Testing
All tests follow the RSpec format and are located in the spec directory.
They can be run with:
@@ -350,11 +418,11 @@
## Changes
### Fixes for votable voter model
-In version 0.8.0, there is bugs for a model that is both votable and voter.
+In version 0.8.0, there are bugs for a model that is both votable and voter.
Some name-conflicting methods are renamed:
+ Renamed Votable.votes to votes_for
+ Renamed Votable.vote to vote_by,
+ Removed Votable.vote_by alias (was an alias for :vote_up)
+ Renamed Votable.unvote_for to unvote_by
@@ -368,19 +436,18 @@
## License
Acts as votable is released under the [MIT
License](http://www.opensource.org/licenses/MIT).
-## TODO
+## Next steps
- Pass in a block of options when creating acts_as. Allow for things
like disabling the aliasing
- Smarter language syntax. Example: `@user.likes` will return all of the votables
that the user likes, while `@user.likes @model` will cast a vote for @model by
@user.
-
- The aliased methods are referred to by using the terms 'up/down' and/or
-'true/false'. Need to come up with guidelines for naming these methods.
+'true/false'. Need to come up with guidelines for naming these methods.
- Create more aliases. Specifically for counting votes and finding votes.