Maintainer or owner wanted: #86
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 bundle HasFriendship, you need to copy migrations and migrate:
$ rails has_friendship_engine:install:migrations
$ rake db:migrate
After gem updates, it may be necessary to run subsequent migrations.
$ rails has_friendship_engine:install:migrations
Will install new migrations if they're necessary.
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]
You can provide custom validations for the friendship
by implementing friendship_errors
method on your Friendable model.
Returning an array with any elements will result in the friendship not being established.
def friendship_errors(wannabe_friend)
return if can_become_friends_with?(wannabe_friend)
[
"Cannot become friends with #{wannabe_friend.email}",
]
end
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
def on_friendship_destroyed(friendship)
...
end