Aparichith
Aparichith

Reputation: 1535

rails self-referential join association

I am working on an API only rails app where I am trying to mimic social media features. Like send request to user, accept/reject request, chat with friends. By referring to this screen-cast, now I am able to add other users as friends.

Bellow is my User model

class User < ApplicationRecord
  has_many :friendships
  has_many :friends, :through => :friendships
  has_many :inverse_friendships, :class_name => "Friendship", :foreign_key => "friend_id"
  has_many :inverse_friends, :through => :inverse_friendships, :source => :user
end

Bellow is Friendship model

class Friendship < ApplicationRecord
  belongs_to :user
  belongs_to :friend, :class_name => 'User'
end

And I have defined routes as bellow to access current user

  resources :users do
    resources :friendships, only: [:create, :destroy]
  end

I can add friends as bellow

current_user = User.find(params[:user_id])
requesting_user = User.find(params[:req_user_id])
current_user.friends << requesting_user

Everything works fine till here.

Can anyone suggest me how to achieve accepting/rejecting a request?

I tried as, having one more FriendRequest model and through that decide whether to add request as friend or not. But not able to do it successfully.

Upvotes: 0

Views: 67

Answers (2)

Duch
Duch

Reputation: 134

I would add a flag to Friendship model - accepted boolean. Then I would add default scope:

../friendship.rb default_scope where(accepted: true)

For pending friends list, create scope:

../user.rb has_many :pending_firends, through: :friendship do def pending where("friendships.accepted = ?", false) end end

I would say that rejecting = removing friendship record. You can add another feature - blocked.

current_user.friends

current_user.pending_firends

But you want to be consist so use:

../friendship.rb scope :accepted, where(accepted: true) scope :pending, where(accepted: false)

../user.rb has_many :pending_firends, -> { pending }, through: :friendship has_many :accepted_firends, -> { accepted }, through: :friendship

It should work, I could make some mistakes.

Upvotes: 1

Pablo
Pablo

Reputation: 3005

The FriendRequest model is a good option.

You could also try to add a status to Friendship (request, accepted, etc) and define scopes in your models to filter requests or friends.

Upvotes: 1

Related Questions