Popular

Gem Version Build Status Code Climate Code Coverage Inline docs Dependency Status

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

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)

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:

@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
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

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:

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:

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