thejchap/popular

View on GitHub
README.md

Summary

Maintainability
Test Coverage
# Popular
[![Gem Version](https://badge.fury.io/rb/popular.png)](http://badge.fury.io/rb/popular)
[![Build Status](https://travis-ci.org/thejchap/popular.svg?branch=master)](https://travis-ci.org/thejchap/popular)
[![Code Climate](https://codeclimate.com/github/thejchap/popular.png)](https://codeclimate.com/github/thejchap/popular)
[![Code Coverage](https://codeclimate.com/github/thejchap/popular/coverage.png)](https://codeclimate.com/github/thejchap/popular)
[![Inline docs](http://inch-ci.org/github/thejchap/popular.png)](http://inch-ci.org/github/thejchap/popular)
[![Dependency Status](https://gemnasium.com/thejchap/popular.svg)](https://gemnasium.com/thejchap/popular)

Popular is a friendship gem designed for Rails/ActiveRecord models.

- RubyGems: ( https://rubygems.org/gems/popular )
- Website: ( http://thejchap.github.io/popular )
- RDoc: ( http://rubydoc.info/github/thejchap/popular/master/frames )

## Installation

Add this line to your application's Gemfile:

    gem 'popular'

And then execute:

    $ bundle

Or install it yourself as:

    $ gem install popular

### Database Migration

Popular uses a friendships table to store friendship relationships.
To get up and running, use the following command:

    rails g popular:migration
    rake db:migrate

## Usage

### Model

To get started using Popular, simply add `popular` to your model, (ie: `app/models/user.rb`)

```ruby
class User < ActiveRecord::Base
  popular
end

@sam = User.create name: "Samuel"
@jackson = User.create name: "Jackson"

# Adding and removing friends
@sam.friends_with? @jackson         #=> false
@sam.friended_by? @jackson          #=> false

@sam.befriend @jackson
@sam.friends_with? @jackson         #=> true

@sam.unfriend @jackson
@sam.friends_with? @jackson         #=> false

@jackson.befriend @sam
@sam.friended_by? @jackson          #=> true

@sam.befriend @jackson
@sam.mutual_friends_with? @jackson  #=> true
```

### Aliases

In Popular, `befriend` is synonomous with `follow`, so if it better fits the context of your application, you can use
follow methods/relations instead. For example:

```ruby
@sam.follow @jackson
@sam.following? @jackson          #=> true

@jackson.follow @sam
@sam.followers.include? @jackson  #=> true
```


### Callbacks

Popular provides callbacks that are fired around friendship creation. Available callbacks are:
  - after_befriend
  - before_befriend
  - after_unfriend
  - before_unfriend


```ruby
class User < ActiveRecord::Base
  popular

  # You can also use a symbol here but the friendship won't be passed to your method
  after_befriend 'notify_friendship_created value'
  after_unfriend 'notify_unfriended value'

  def notify_friendship_created(friendship)
    puts "#{name} friended #{friendship.friend.name}"
  end

  def notify_unfriended(friendship)
    puts "#{name} unfriended #{friendship.friend.name}"
  end
end

@justin = User.create name: "Justin"
@jenny = User.create name: "Jenny"

@justin.befriend @jenny #=> "Justin friended Jenny"
@justin.unfriend @jenny #=> "Justin unfriended Jenny"
```

### Customization

Popular is intended to provide basic utilities around self-referential relationships in social apps.
Often, more customization is necessary. If you would like to store more information around the friendship,
Popular provides a hook to connect its `friendship` model to a user defined `friendship_profile` model. 
This allows Popular to remain somewhat lightweight and factor out only the code that is repeated  alot between apps,
while allowing flexibility where it is needed.

Do to this, create a `FriendshipProfile` model that belongs to `friendship`, and has whatever custom attributes
you want

```ruby
rails g model FriendshipProfile friendship:belongs_to meeting_location:string meeting_latitude:float meeting_longitude:float
rake db:migrate
```

Then, in your Popular model, just set the `friendship_profile` option to true:

```ruby
class User < ActiveRecord::Base
  popular friendship_profile: true
end
```

Now, everytime a `friendship` is created, an accompanying `friendship_profile` will be attached to it, allowing you to define
as many custom attributes as you wish in a separate table

## Related gems

If Popular isn't quite what you're looking for, here are some other useful gems in the same category:

- Amistad ( https://github.com/raw1z/amistad )
- Friendable ( https://github.com/yuki24/friendable )

*Disclaimer: I have not used either of the above gems*


## Resources

Popular was heavily inspired by this screencast: ( http://railscasts.com/episodes/163-self-referential-association?view=asciicast )


## Plans for the future
- Add generator for entire `Frienship` resource that includes FriendshipsController, routes, etc
- More aliases
- Define your own `FriendshipProfile` class
- Callbacks for `befriended` or `followed`



## Contributing

1. Fork it ( http://github.com/thejchap/popular/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request