Coder Social home page Coder Social logo

has_friendship's Introduction

(UNMAINTAINED) HasFriendship Build Status Coverage Status

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.

Getting started

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

Gem upgrades

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.

Usage

Simply drop in has_friendship to a model:

class User < ActiveRecord::Base
  has_friendship
end

Managing 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}",
  ]
end

Callbacks

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

has_friendship's People

Contributors

adambutler avatar armandomendoza avatar atarihomestar avatar chevinbrown avatar chinloongtan avatar d4be4st avatar dependabot[bot] avatar duderamos avatar eblohm avatar f-anthonioz avatar kdonovan avatar maximed avatar mswiszcz avatar sbadura avatar skycocker avatar sungwoncho avatar syd avatar t3tr0 avatar xilefff avatar yinfei avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

has_friendship's Issues

Clarification in the docs

Hey, first off, THANKS! This gem is awesome

One Issue I am having (due to the fact I'm new to rails and Ruby, not an issue with your gem) is implementing it in a form.

Could you provide an example of how one would implement it from controller to view?
for example, I have the following.

<% @users.each do |user| %>
      <% if user.pending_friends %>

      <%= form_tag @user.accept_request(user), method: :post, remote: true do %>
      <%= button_tag 'Accept Friend Request', class: 'btn btn-primary' %>

      <%= form_tag @user.decline_request(user), method: :post, remote: true do %>
      <%= button_tag 'Deny Friend Request', class: 'btn btn-primary' %>

      <% end %>
<% end %>

and the first form tag throws
undefined method `update' for nil:NilClass

the controller is bellow

class FriendsController < ApplicationController
  before_action :set_user, :authenticate_user!
  respond_to :js

  def show
    @users = User.near(@user.address, 30)
    @user = current_user
  end
  def update
  end
  private
  def set_user
    @user = current_user
  end
end

I can submit a PR for documentation once I know what the proper implementation use

Specify the Rails release that migration is for

rake db:migrate fails

Nothing huge, but got the error "Directly inheriting from ActiveRecord::Migration is not supported. Please specify the Rails release the migration was written for:"

Easy fix, just add [4.2] to all the migration files such as "class CreateFriendships < ActiveRecord::Migration" to "class CreateFriendships < ActiveRecord::Migration[4.2]".

Would be nice if generators could check rails version and add this or at least update Readme for others.

Rails: 5.1.4
has_friendship: 1.1.1

Don't see value inside friendships tables after use friend_request

Hi,

I am trying to use this gem in my simple app and I created controller action and provide and everything goes well but when I trying to check pending_friends I am getting "#User::ActiveRecord_Associations_CollectionProxy:0xa690f68"

Is my controller action code correct ?

def add_friend
@user = User.find_by_name(params[:id])
if @user != current_user
current_user.friend_request(@user)
redirect_to root_path
end
end

A blockee can unblock friend with the blocker

Hi there,
First of all I am not sure if this situation is expected, when userA blocks userB, userA will also get blocked by userB.

If it is true, then I just tried something like:
@userA.block_friend(@userb)
@userB.unblock_friend(@usera)

It actually worked and removed userB from userA's blocked list, which should not happen as described in README.

I am wondering if anybody else has the same issue or just me doing something wrong?

Any answer or clarification is appreciated, thanks!

Migration Error

ArgumentError: Algorithm must be one of the following: :default, :copy, :inplace

I get this when I simply run rails db:migrate

Friendship model: Dependent destroy doesn't work correctly on friend association

When a friend or friendable is destroyed it should destroy all its friendships too. It works out of the box on the friendable relation but not on the friend one

Here is a set of specs illustrating the problem:

context "Callbacks" do
  let(:friend) { create :user }
  let(:friendable) { create :user }
  let!(:friendship) { HasFriendship::Friendship.create(friend: friend, friendable: friendable, status: "accepted") }

  it "destroys friendship on friend destroy" do
    # Spec doesn't pass :(
    expect { friend.destroy }.to change { HasFriendship::Friendship.count }.by(-1)
  end

  it "destroys friendship on friendable destroy" do
    # Spec succeeds
    expect { friendable.destroy }.to change { HasFriendship::Friendship.count }.by(-1)
  end
end

I will try to submit a PR if I can find time to work on this

Deleting the request by the requester?

Facebook allows to roll back the "Add Friend" request. I am looking for such a method in has_friendship

Like:

@mac.friend_request(@foo)
# The above one might be by mistake, mac doesn't really want to send a request to foo
# Allow the following
@mac.delete_request(@foo)
# Now mac can be happy

As of now, I have the following in my user.rb I think this will be an useful method to be incorporated into the gem.

def delete_request(f)
    HasFriendship::Friendship.find_by('friend_id = :cur and friendable_id = :other', cur: id, other: f.id).destroy
    HasFriendship::Friendship.find_by('friend_id = :other and friendable_id = :cur', cur: id, other: f.id).destroy
end

[Feature request] Additional relations

Hey. I would like to access the friendship records

For example the created_at column, so I could say "John sent you a friend request 3 days ago".

At the moment I only get the user record.

This works fine in one case, like current_user.friends can be changed to current_user.friendships, and then i can serialize it nicely in api-mode:

class Api::V1::FriendshipSerializer < ActiveModel::Serializer
  attributes :id
  belongs_to :friend
end

But its missing for requested/pending/blocked. These would be nice :)

current_user.requested_friendships
current_user.pending_friendships
current_user.blocked_friendships

Thanks

Doesn't work with rails 6.1

You still haven't added support for activestorage 6.1 which goes together with rails 6.1 so you never added support for rails 6.1

Rails 5

Ensure the gem can be used in Rails 5

No way to rollback the migrations

To reproduce the issue on V1.0.0:

rails generate has_friendship
rake db:migrate
rake db:rollback STEP=3
rake db:migrate

This is due to the absence of down method in CreateFriendships migration.

Friendship between two models

Hi,
Is it possible to create friendship between two models, I am not sure if its right but the idea is more like this:
User1 with Manager role will add a POST1
User2 with Coworker role can send a request to join POST1 to be a Team member of POST1.
User1 can send request to let user2 be part of Teams
User1/User2 can approve or reject if they got request.
If anyone removes the relation so it's removed from both.

Any idea or way to do that.
Thanks

Block a friendable

It might be a good thing to allow to block a friendable from sending a friend request.

friends_with? returns true if users are not friends

User1 sends request to user2
user1.friend_request(user2)
And now even if user2 hasn't accepted friend request from user1, friends_with? return true

user1.friends_with?(user2)
=> true
user2.friends_with?(user1)
=> true

Issue on Unblock Friend.

I am phasing one issue on unblock. when i perform block at that time only status change. but when i unblock perform at that time entry remove from table instead of status change.

So after unblock no and relation with one user to another for friend.

Example .

 # @mac sends a friend request to @dee
  1 ) @mac.friend_request(@dee)

@dee can accept the friend request 
 2) @dee.accept_request(@mac)

 # @mac blocks @dee from making any more friendship actions
3) @mac.block_friend(@dee)

# @mac unblocks @dee
# Only @mac can perform this action
4)@mac.unblock_friend(@dee)

after doing this @mac and @dee not friends because of record delete.

blocked_friends

Hello,

Thanks for the gem, it has been very helpful.

Just a heads-up, user.blocked_friends spawn an error.

I fixed it by addind source: :friend in the file lib/has_friendship/friendable.rb to the line (15) defining the call.

Check for multiple users & if there is any relationship at all?

Is there any way to check if a user is friends with multiple users? Also I would like to be able to create multiple friendships in one query.

Also is there any way to check for any kind of relationships rather than the friends_with? because if someone have been blocked this wont be true. I would like a function to check if there are any relationship at all between two users.

NoMethodError: undefined method `destroy' for nil:NilClass

When i trying remove friend/decline request with user, which is not my friend i have this error.

NoMethodError: undefined method "destroy" for nil:NilClass.

I fixed bug with this hotfix.

    def decline_request(friend)
      super
    rescue NoMethodError
      nil
    end

I think, need rewrite code design related with Friendship model. I can help with it.

Getting NoMethodError undefined method 'accept!' for #<HasFriendship::Friendship:0x99c67b0>

I'm honestly not sure why this is happening. Yesterday friendships could be accepted but now today they cannot. I haven't changed any code in the controller, and users can still request other users just fine, but now when a user tries to accept a request I get that error.

Here's my code in my controller for accepting friendships:
def accept
new_friend = User.find_by(username: params[:friend])
current_user.accept_request(new_friend)
flash[:notice] = "Successfully added #{new_friend.username}!"
redirect_to root_url
end

Like I said, this code was working fine yesterday, and I haven't touched anything related to friendships gem since it was working.

Edit: it looks like this might have something to do with the newest commit that was pushed yesterday, actually. Do I need to add more code now? Or run a new migration for something?

Getting error while using rails generate has_friendship

siddhardha@sidddhardha:~/billpin$ rails generate has_friendship
/home/siddhardha/.rvm/gems/ruby-2.2.0/gems/orm_adapter-0.5.0/lib/orm_adapter/adapters/active_record.rb:81: warning: already initialized constant ActiveRecord::Base::OrmAdapter
/home/siddhardha/.rvm/gems/ruby-2.2.0/gems/orm_adapter-0.5.0/lib/orm_adapter/adapters/active_record.rb:81: warning: previous definition of OrmAdapter was here
/home/siddhardha/.rvm/gems/ruby-2.2.0/gems/orm_adapter-0.5.0/lib/orm_adapter/adapters/active_record.rb:81: warning: already initialized constant ActiveRecord::Base::OrmAdapter
/home/siddhardha/.rvm/gems/ruby-2.2.0/gems/orm_adapter-0.5.0/lib/orm_adapter/adapters/active_record.rb:81: warning: previous definition of OrmAdapter was here
/home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activerecord-4.1.8/lib/active_record/dynamic_matchers.rb:26:in `method_missing': undefined method `raise_in_transactional_callbacks=' for #<Class:0x000000037c7448> (NoMethodError)
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activerecord-4.1.8/lib/active_record/railtie.rb:110:in `block (3 levels) in <class:Railtie>'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activerecord-4.1.8/lib/active_record/railtie.rb:109:in `each'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activerecord-4.1.8/lib/active_record/railtie.rb:109:in `block (2 levels) in <class:Railtie>'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activesupport-4.1.8/lib/active_support/lazy_load_hooks.rb:38:in `instance_eval'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activesupport-4.1.8/lib/active_support/lazy_load_hooks.rb:38:in `execute_hook'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activesupport-4.1.8/lib/active_support/lazy_load_hooks.rb:45:in `block in run_load_hooks'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activesupport-4.1.8/lib/active_support/lazy_load_hooks.rb:44:in `each'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activesupport-4.1.8/lib/active_support/lazy_load_hooks.rb:44:in `run_load_hooks'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activerecord-4.1.8/lib/active_record/base.rb:326:in `<module:ActiveRecord>'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activerecord-4.1.8/lib/active_record/base.rb:23:in `<top (required)>'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/devise-3.5.2/lib/devise/orm/active_record.rb:3:in `<top (required)>'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activesupport-4.1.8/lib/active_support/dependencies.rb:247:in `require'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activesupport-4.1.8/lib/active_support/dependencies.rb:247:in `block in require'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activesupport-4.1.8/lib/active_support/dependencies.rb:232:in `load_dependency'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activesupport-4.1.8/lib/active_support/dependencies.rb:247:in `require'
    from /home/siddhardha/billpin/config/initializers/devise.rb:24:in `block in <top (required)>'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/devise-3.5.2/lib/devise.rb:278:in `setup'
    from /home/siddhardha/billpin/config/initializers/devise.rb:3:in `<top (required)>'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activesupport-4.1.8/lib/active_support/dependencies.rb:241:in `load'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activesupport-4.1.8/lib/active_support/dependencies.rb:241:in `block in load'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activesupport-4.1.8/lib/active_support/dependencies.rb:232:in `load_dependency'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activesupport-4.1.8/lib/active_support/dependencies.rb:241:in `load'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/railties-4.1.8/lib/rails/engine.rb:648:in `block in load_config_initializer'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activesupport-4.1.8/lib/active_support/notifications.rb:161:in `instrument'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/railties-4.1.8/lib/rails/engine.rb:647:in `load_config_initializer'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/railties-4.1.8/lib/rails/engine.rb:612:in `block (2 levels) in <class:Engine>'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/railties-4.1.8/lib/rails/engine.rb:611:in `each'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/railties-4.1.8/lib/rails/engine.rb:611:in `block in <class:Engine>'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/railties-4.1.8/lib/rails/initializable.rb:30:in `instance_exec'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/railties-4.1.8/lib/rails/initializable.rb:30:in `run'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/railties-4.1.8/lib/rails/initializable.rb:55:in `block in run_initializers'
    from /home/siddhardha/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/tsort.rb:226:in `block in tsort_each'
    from /home/siddhardha/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/tsort.rb:348:in `block (2 levels) in each_strongly_connected_component'
    from /home/siddhardha/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/tsort.rb:420:in `block (2 levels) in each_strongly_connected_component_from'
    from /home/siddhardha/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/tsort.rb:429:in `each_strongly_connected_component_from'
    from /home/siddhardha/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/tsort.rb:419:in `block in each_strongly_connected_component_from'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/railties-4.1.8/lib/rails/initializable.rb:44:in `each'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/railties-4.1.8/lib/rails/initializable.rb:44:in `tsort_each_child'
    from /home/siddhardha/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/tsort.rb:413:in `call'
    from /home/siddhardha/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/tsort.rb:413:in `each_strongly_connected_component_from'
    from /home/siddhardha/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/tsort.rb:347:in `block in each_strongly_connected_component'
    from /home/siddhardha/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/tsort.rb:345:in `each'
    from /home/siddhardha/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/tsort.rb:345:in `call'
    from /home/siddhardha/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/tsort.rb:345:in `each_strongly_connected_component'
    from /home/siddhardha/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/tsort.rb:224:in `tsort_each'
    from /home/siddhardha/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/tsort.rb:203:in `tsort_each'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/railties-4.1.8/lib/rails/initializable.rb:54:in `run_initializers'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/railties-4.1.8/lib/rails/application.rb:300:in `initialize!'
    from /home/siddhardha/billpin/config/environment.rb:5:in `<top (required)>'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activesupport-4.1.8/lib/active_support/dependencies.rb:247:in `require'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activesupport-4.1.8/lib/active_support/dependencies.rb:247:in `block in require'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activesupport-4.1.8/lib/active_support/dependencies.rb:232:in `load_dependency'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/activesupport-4.1.8/lib/active_support/dependencies.rb:247:in `require'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/spring-1.4.0/lib/spring/application.rb:92:in `preload'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/spring-1.4.0/lib/spring/application.rb:143:in `serve'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/spring-1.4.0/lib/spring/application.rb:131:in `block in run'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/spring-1.4.0/lib/spring/application.rb:125:in `loop'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/spring-1.4.0/lib/spring/application.rb:125:in `run'
    from /home/siddhardha/.rvm/gems/ruby-2.2.0/gems/spring-1.4.0/lib/spring/application/boot.rb:18:in `<top (required)>'
    from /home/siddhardha/.rvm/rubies/ruby-2.2.0/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
    from /home/siddhardha/.rvm/rubies/ruby-2.2.0/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
    from -e:1:in `<main>'

This is the error log.

rails db:migrate failing

Hi,

I am using

Rails 5.1.6
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-linux]
has_friendship-1.1.1

While trying to run migration, it is giving bellow error

rails aborted!

StandardError: An error has occurred, this and all later migrations canceled:

Directly inheriting from ActiveRecord::Migration is not supported. Please specify the Rails release the migration was written for:

  class CreateFriendships < ActiveRecord::Migration[4.2]

Though it can be cleared by overriding all the has_friendship migration files by inserting appropriate rails version like bellow

class CreateFriendships < ActiveRecord::Migration[5.1]
# 
end

Was it missed from the gem or did I missed anything while installing gem?

Dont work with rails 5.1.3

Bundler could not find compatible versions for gem "rails":
In snapshot (Gemfile.lock):
rails (= 5.1.3)

In Gemfile:
rails (~> 5.1.3)

has_friendship (~> 1.1) was resolved to 1.1.0, which depends on
  rails (< 5.1.0, >= 4.0.0)

Polimorfic association is incomplete

The polimorfic association we have right now does not uniquely define a relation. And can bring wrong results.
Ex
We have two tables: Men, Women
When we call find_relation we might find relationships withing Men and Women as well as Men/Men & Women/Women.

Rails 6.1 support

On rails 6.1 I got this one error:

Bundler could not find compatible versions for gem "activemodel":
  In snapshot (Gemfile.lock):
    activemodel (= 6.1.1)

  In Gemfile:
    has_friendship was resolved to 1.1.8, which depends on
      activemodel (< 6.1, >= 4.2.0)

    rails (~> 6.1.0) was resolved to 6.1.1, which depends on
      activemodel (= 6.1.1)

Running `bundle update` will rebuild your snapshot from scratch, using only
the gems in your Gemfile, which may resolve the conflict.

Bundler could not find compatible versions for gem "rails":
  In snapshot (Gemfile.lock):
    rails (= 6.1.1)

  In Gemfile:
    rails (~> 6.1.0)

    has_friendship was resolved to 0.0.3, which depends on
      rails (~> 4.1.8)

Running `bundle update` will rebuild your snapshot from scratch, using only
the gems in your Gemfile, which may resolve the conflict.

Can we expect support for rails 6.1 in the near future?

bundler tries to download old version of has_friendship gem

I keep getting this error:

Bundler could not find compatible versions for gem "rails":
  In Gemfile:
    rails (~> 5.2.1)

    has_friendship was resolved to 0.0.3, which depends on
      rails (~> 4.1.8)

The error could be on my part because the gemspec seems to support rails up to 5.3.0.

EDIT:
I took a look at rubygems.org and noticed the version here and there are not consistent. I then attempted to state that version in my gemfile, but alas the gem depends on rails < 5.2.0 while I am on 5.2.1.

I noticed that there was discussion about the owner not being able to maintain this repo and a @chevinbrown has volunteered to be a maintainer, so I'll just await the decision then. For now a simple solution is to install the gem using this git source as at least it's compatible with rails up to 5.3.0:

gem 'has_friendship', git: '[email protected]:sungwoncho/has_friendship.git'

Rdoc

Add API documenation

Using UUID as primary key

Could help others if readme had some pointers on how to use this gem with UUID's as primary key for associations?

Assumptions, User model has UUID as primary key and using enable_extension 'pgcrypto'.

Then alter the following migration files:
..._create_friendships.rb > NOTE t.references :friendable, polymorphic: true, type: :uuid and t.uuid :friend_id

def self.up
  create_table :friendships do |t|
    t.references :friendable, polymorphic: true, type: :uuid
    t.uuid  :friend_id
    t.string   :status

    t.timestamps
  end
end

..._add_blocker_id_to_friendships.rb > NOTE change from :string to :uuid

def self.up
  add_column :friendships, :blocker_id, :uuid, default: nil
end

Separate table/model for friendship blocking records

friendship table contains too much information, it would be nice if some of them are decoupled.

I think it'd be a good idea to make a separate table/model for records for friendship block/unblock, with blocker_id and blockee_id.

Maintainer or new owner wanted

I am no longer maintaining this package, and am looking for a new maintainer or an owner. Thanks @chevinbrown for your support thus far, by the way.

Please register your interests in this issue.

1.1.0 - NoMethodError: undefined method `on_friendship_created' for nil:NilClass

Since I upgraded from 1.0.2 to the latest update, 1.1.0, I get an error when I do a basic friend request:

a = User.last
b = User.new
a.friend_request(b)

When entering in those commands, I get this error, which looks like an issue with the new callbacks feature.

NoMethodError: undefined method `on_friendship_created' for nil:NilClass

/gems/ruby-2.4.1/gems/has_friendship-1.1.0/lib/has_friendship/friendship.rb:5:in `block in <class:Friendship>'
/gems/ruby-2.4.1/gems/activesupport-5.0.4/lib/active_support/callbacks.rb:396:in `instance_exec'
/gems/ruby-2.4.1/gems/activesupport-5.0.4/lib/active_support/callbacks.rb:396:in `block in make_lambda'
...
/gems/ruby-2.4.1/gems/has_friendship-1.1.0/lib/has_friendship/friendship.rb:46:in `create_relation'
/gems/ruby-2.4.1/gems/has_friendship-1.1.0/lib/has_friendship/friendable.rb:46:in `block in friend_request'
...
/gems/ruby-2.4.1/gems/has_friendship-1.1.0/lib/has_friendship/friendable.rb:45:in `friend_request'

All else is in order, and the gem works perfectly once I simply downgrade to 1.0.2

rails 7 support

i tried gem 'has_friendship', github: 'sungwoncho/has_friendship' but it doesn't work for rails 7.

any way to update?

most rails 5 style approach should work in 7. let me know if anyone has a fork or branch.

thank you.

Database indexes

Was just wondering if database indexes and foreign key constraints were left out for a specific reason ?
If not, I can add those for performance sake.

Either friend can unblock a blocked friendship

The blocker_id is not consistent between the two friendship objects, therefore either user can unblock a blocked friendship.

2.6.1 :059 > user1.friend_request(user2)
HasFriendship::Friendship Exists (0.4ms) SELECT 1 AS one FROM "friendships" WHERE "friendships"."friendable_id" = $1 AND "friendships"."friendable_type" = $2 AND "friendships"."friend_id" = $3 LIMIT $4 [["friendable_id", 1], ["friendable_type", "User"], ["friend_id", 49], ["LIMIT", 1]]
(0.1ms) BEGIN
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 49], ["LIMIT", 1]]
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
HasFriendship::Friendship Create (0.2ms) INSERT INTO "friendships" ("friendable_type", "friendable_id", "friend_id", "created_at", "updated_at", "status") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["friendable_type", "User"], ["friendable_id", 1], ["friend_id", 49], ["created_at", "2021-02-20 05:40:37.589275"], ["updated_at", "2021-02-20 05:40:37.589275"], ["status", 0]]
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 49], ["LIMIT", 1]]
HasFriendship::Friendship Create (0.2ms) INSERT INTO "friendships" ("friendable_type", "friendable_id", "friend_id", "created_at", "updated_at", "status") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["friendable_type", "User"], ["friendable_id", 49], ["friend_id", 1], ["created_at", "2021-02-20 05:40:37.591793"], ["updated_at", "2021-02-20 05:40:37.591793"], ["status", 1]]
(5.5ms) COMMIT
=> true
2.6.1 :060 > user2.block_friend(user1)
(0.1ms) BEGIN
HasFriendship::Friendship Load (0.2ms) SELECT "friendships".* FROM "friendships" WHERE "friendships"."friendable_id" = $1 AND "friendships"."friendable_type" = $2 AND "friendships"."friend_id" = $3 AND "friendships"."status" != $4 ORDER BY "friendships"."id" ASC LIMIT $5 [["friendable_id", 49], ["friendable_type", "User"], ["friend_id", 1], ["status", 3], ["LIMIT", 1]]
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 49], ["LIMIT", 1]]
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
HasFriendship::Friendship Update (0.3ms) UPDATE "friendships" SET "status" = $1, "blocker_id" = $2, "updated_at" = $3 WHERE "friendships"."id" = $4 [["status", 3], ["blocker_id", 49], ["updated_at", "2021-02-20 05:40:51.383270"], ["id", 8]]
HasFriendship::Friendship Load (0.1ms) SELECT "friendships".* FROM "friendships" WHERE "friendships"."friendable_id" = $1 AND "friendships"."friendable_type" = $2 AND "friendships"."friend_id" = $3 AND "friendships"."status" != $4 ORDER BY "friendships"."id" ASC LIMIT $5 [["friendable_id", 1], ["friendable_type", "User"], ["friend_id", 49], ["status", 3], ["LIMIT", 1]]
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 49], ["LIMIT", 1]]
HasFriendship::Friendship Update (0.3ms) UPDATE "friendships" SET "status" = $1, "blocker_id" = $2, "updated_at" = $3 WHERE "friendships"."id" = $4 [["status", 3], ["blocker_id", 1], ["updated_at", "2021-02-20 05:40:51.386480"], ["id", 7]]
(5.4ms) COMMIT
=> true
2.6.1 :061 > HasFriendship::Friendship.first
HasFriendship::Friendship Load (0.3ms) SELECT "friendships".* FROM "friendships" ORDER BY "friendships"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> #<HasFriendship::Friendship id: 7, friendable_type: "User", friendable_id: 1, friend_id: 49, created_at: "2021-02-20 05:40:37", updated_at: "2021-02-20 05:40:51", blocker_id: 1, status: "blocked">
2.6.1 :062 > HasFriendship::Friendship.last
HasFriendship::Friendship Load (0.4ms) SELECT "friendships".* FROM "friendships" ORDER BY "friendships"."id" DESC LIMIT $1 [["LIMIT", 1]]
=> #<HasFriendship::Friendship id: 8, friendable_type: "User", friendable_id: 49, friend_id: 1, created_at: "2021-02-20 05:40:37", updated_at: "2021-02-20 05:40:51", blocker_id: 49, status: "blocked">


The blocker_id is always getting set to the friendable_id. Instead, the blocker_id should be set to the id of the friend who called block!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.