Add friendship features to your ActiveRecord models.
HasFriendship allows ActiveRecord objects to send, accept, and decline friend requests using self-refernetial polymorphic association.
Getting started
Setup
To start using HasFriendship in an ActiveRecord Model, simply add has_friendship to the model file:
gem 'has_friendship'When HasFriendship is bundled into your application, a new Rake task called
has_friendship_engine:install:migrations will be added. Use this Rake task to
generate the database migration, and then apply it to your project:
$ rails has_friendship_engine:install:migrations
$ # (inspect the migration files, and change if necessary)
$ rails db:migrate
By default, the friendship table uses integer as the friend_id datatype. If
your project requires a different datatype, like a UUID, then you'll need to
edit the migration file before running the migration.
Gem upgrades
After this gem is updated, there may be new migrations that are needed. If so,
you will be prompted to rerun rails has_friendship_engine:install:migrations
and apply the latest changes. (The rake task won't do anything if no new
migrations are needed.)
Usage
Simply drop in has_friendship to a model:
class User < ActiveRecord::Base
has_friendship
endManaging friendship
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)Blocking a friendable
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)Checking friendship
# Check if there is an accepted friendship between @mac and @dee
@mac.friends_with?(@dee)Type of friends
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.
requested_friends
Instances that sent friend request that has not been accepted.
@mac.friend_request(@dee)
@dee.requested_friends # => [@mac]pending_friends
Instances that received but has not accepted the friend request.
@mac.friend_request(@dee)
@mac.pending_friends # => [@dee]blocked_friends
Instances that are blocked from taking any friendship actions
@dee.friend_request(@mac)
@mac.block_friend(@dee)
@mac.blocked_friends # => [@dee]friends
Instances with accepted Friendship.
@mac.friend_request(@dee)
@dee.accept_request(@mac)
@mac.friends # => [@dee]
@dee.friends # => [@mac]Custom validations
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}",
]
endCallbacks
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)
...
endHow To Build
Clone the repo, go into the top directory, and run bundle install. Then, run
bundle exec rake spec to run all the RSpec test cases. Finally, run bundle exec rake build to actually build the Gem.
Note that there is a small instance of Rails in the spec/ environment. If you
need to make changes to Rails environment, and want to run the Rails commands,
you should:
cd spec/internal/bundle exec --gemfile ../../Gemfile -- ${your_command}
How to test
You can run the RSpec tests in your development environment by running
bundle exec rake spec.
Or, if you wish to run the compatibility tests on different versions of Rails, you can run the Appraisals-based tests by running bundle exec appraisal rake spec.