Add friendship features to your ActiveRecord models.
HasFriendship allows ActiveRecord objects to send, accept, and decline friend requests using self-refernetial polymorphic association.
Add HasFriendship to your Gemfile:
gem 'has_friendship'
After you install HasFriendship, you need to run the generator:
$ rails generate has_friendship
The generator will copy a migration that creates friendships
table. Run the migration to finish the setup.
$ rake db:migrate
0.1.0
adds a blocking feature for friendables. This requires an additional
column in the friendships
table, and a migration should be run. You will need
to run the generator and run the new migration.
If upgrading from <= 0.1.3 to 1.x.x, please run the following generator:
$ rails generate has_friendship_update
Then, run the migration:
$ rake db:migrate
Simply drop in has_friendship
to a model:
class User < ActiveRecord::Base
has_friendship
end
Now, instances of User
can send, accept, and decline friend requests:
@mac = User.create(name: "Mac")
@dee = User.create(name: "Dee")
# @mac sends a friend request to @dee
@mac.friend_request(@dee)
# @dee can accept the friend request
@dee.accept_request(@mac)
# @dee can also decline the friend request
@dee.decline_request(@mac)
A friendship can also be removed:
# @dee removes @mac from its friends
@dee.remove_friend(@mac)
A friendable can be blocked. When blocked, the friendable cannot request or remove friendship to the one that initially blocked it.
@dee.request_friend(@mac)
# @mac blocks @dee from making any more friendship actions
@mac.block_friend(@dee)
# @mac unblocks @dee
# Only @mac can perform this action
@mac.unblock_friend(@dee)
# Check if there is an accepted friendship between @mac and @dee
@mac.friends_with?(@dee)
There are four types of friends:
- requested_friends
- pending_friends
- blocked_friends
- friends
Each type returns an array of friends, which should be looped through to access specific friends. They can be accessed using association.
Instances that sent friend request that has not been accepted.
@mac.friend_request(@dee)
@dee.requested_friends # => [@mac]
Instances that received but has not accepted the friend request.
@mac.friend_request(@dee)
@mac.pending_friends # => [@dee]
Instances that are blocked from taking any friendship actions
@dee.friend_request(@mac)
@mac.block_friend(@dee)
@mac.blocked_friends # => [@dee]
Instances with accepted Friendship.
@mac.friend_request(@dee)
@dee.accept_request(@mac)
@mac.friends # => [@dee]
@dee.friends # => [@mac]
To use callbacks you can add methods described below, to your Friendable model.
def on_friendship_created(friendship)
...
end
def on_friendship_accepted(friendship)
...
end
def on_friendship_blocked(friendship)
...
end
Thanks for all the contributors. Pull requests are encouraged for the following features.
- Make a separate table/model for friendship blocking records, with
blocker_id
andblockee_id
. Currently,Friendship
model is kind of bloated. - Implement state machine for friendship status. (#24)