# LikesTracker [![Build Status](https://secure.travis-ci.org/apeacox/likes_tracker.png)](http://travis-ci.org/apeacox/likes_tracker) A Rails gem to track *likes* between two ```ActiveModel``` compliant models. A common use case might be that a User likes a Post. ## Installation Add this line to your application's Gemfile: ```gem 'likes_tracker'``` And then execute: ```$ bundle install``` Or install it yourself as: ```$ gem install likes_tracker``` ### Dependencies * [redis](http://redis.io) * ruby 1.9+ (it uses some 1.9's syntax) ## Usage First of all, you need a ```$redis``` in your app, you might achieve this using an initializer: ``` # config/initializers/redis.rb $redis = Redis.new(host: 'localhost', port: '6379', db: '1') ``` Given you have two models, say User and Post, and you want to track the *likes* a given Post receives by User(s). Include the LikesTracker module and use the methods it offers to setup models as *liker* and *liked*: ``` # app/models/post.rb class Post < ActiveRecord::Base include LikesTracker acts_as_liked_by :users # rest of the code end # app/models/user.rb class User < ActiveRecord::Base include LikesTracker acts_as_liker_for :posts # rest of the code end ``` Now your models will have some methods to manage the likes a model *gives* to another. Following the above example: ``` > user.likes_post? post => false > user.liked_posts => [] > post.likes_users_count => 0 > user.like_post! post => [true, true, 1.0] > user.likes_post? post => true ``` As you can see, the methods' names reflect model names (and they'll be properly namespaced on Redis). This means, that the same models can like several others, for example User might like another model called Photo or Comment, so you'll have methods like ```#like_comment!``` or ```#likes_photo?``` and so on. How to find Posts liked by a User? There's a method for this, of course ;-) ``` > user.liked_posts => [#] ``` It returns a *relation*, such as ```ActiveRecord::Relation```. Even if I haven't tested it yet, this *should* work with other ORMs like Mongoid. ``` # a silly example to show how it works > user.liked_posts {|model, ids| p [model, ids] } => [Post(id: integer, ...), ["1"]] # the query executed by default > user.liked_posts {|model, ids| model.where(id: ids) } => [#] ``` Last but not least, here there're the remaining methods and examples: ``` # you can provide a *limit* parameter, if omitted it defaults to 5 > Post.most_liked(5) => [#] # and it also accepts an *offset* parameter, if omitted it defaults to 0 > Post.most_liked(5, 0) => [#] # last but not least, it accepts a block, like you've already seen in above examples > Post.most_liked(5, 0) {|model, ids| p [model, ids] } => [Post(id: integer, ...), ["1"]] > post.likes_users_count => 1 > user.unlike_post! post => [true, true, 0.0] > user.likes_post? post => false > user.liked_posts => [] > post.likes_users_count => 0 ``` ## Contributing 1. Fork it! 2. Create your feature branch (`git checkout -b my-new-feature`) 3. Commit your changes (`git commit -am 'Added some feature'`) 4. Push to the branch (`git push origin my-new-feature`) 5. Create new Pull Request ### Testing * clone this repo * run `bundle install` * run `rspec spec` ## License Copyright (c) 2012 Andrea Pavoni http://andreapavoni.com