-1

I am trying to define a model relationship that I believe is extremely ordinary, but I just could not find any elegant way to do it in Laravel. I'm talking about a same-model m:n relationship. Let's say you want to define a friends relationship:

class User extends Model
{
    public function friends(): BelongsToMany
    {
        return $this->belongsToMany(User::class, 'friends');
    }
}

Well, this won't work both ways, because you might probably expect a table similar to this:

friends:
 - (int) id
 - (int) first_user_id
 - (int) second_user_id
 - (bool) is_accepted (default 0)

And now, in the model, you would have been supposed to define the foreign key names. Which one is foreign? The typical use case is that one user will send a request to another, and then the other one will accept/reject it. But you will have to assign the users to that M:N relationship, you will have to do some validation (e.g., aren't they friends already?), you will have to check if the other user didn't already send a request (which is pending) to the first one and so on. However, I am trying to avoid something like the following.

class User extends Model
{
    public function myFriends(): BelongsToMany
    {
        return $this->belongsToMany(User::class, 'friends', 'first_user_id', 'second_user_id');
    }

    public function friendOf(): BelongsToMany
    {
        return $this->belongsToMany(User::class, 'friends', 'second_user_id', 'first_user_id');
    }
}

I am trying to think of a data structure that would allow this to happen as a classic relationship, but I could not quite get to it. Any ideas? Is it even possible while keeping the traditional Eloquent-relationship methods?

Karl Hill
  • 12,937
  • 5
  • 58
  • 95
  • https://stackoverflow.com/questions/45450045/laravel-eloquent-relationship-for-user-to-friends/45450547 – HashtagForgotName Feb 10 '22 at 18:52
  • @HashtagForgotName That won't work in both directions. If you will do `$me->frineds()`, you will only get friends, where your `id` is in the `user_id` column. Not those, where you are in the `friend_id` column. – David Sojka Feb 10 '22 at 18:59
  • I can see but i assume that u want to accomplish that user can create friends in your code // application that that's the way how u can implements it and u can still add `(bool) is_accepted (default 0)` the friends table if u still want to make that accept and deny method – HashtagForgotName Feb 10 '22 at 19:05
  • "I am trying to avoid something like this" why? That's how it's done. – miken32 Feb 10 '22 at 22:58
  • seconded, a pivot is the way forward here as @HashtagForgotName has linked. – MHewison Feb 10 '22 at 23:16
  • @miken32 Because every work with *friends* will basically be doubled. Saving, retrieving, modifying, verifying,... I can make some helping methods for the basic operations, but I was trying to keep up with the Eloquent conventions. – David Sojka Feb 11 '22 at 07:32

1 Answers1

-1

You can define a new class and table "frienduser" which has three inputs
'user_1','user-2','is_accepted'
user_1 is sender
user_2 for receiver


Friends table contains duplicate data.
id,user_id,friend_id,friend_user_id
1,1,2,1
2,2,1,1
class FriendUser extends Model
{
    protected $table = 'friend_user';

    use HasFactory;
  
}

Friend class

class Friend extends Model
{
    use HasFactory;
    public function friend_info()
    {
        return $this->belongsTo(User::class,'friend_id');
    }
      public function friend_user()
    {
        return $this->hasOne('App\Models\FriendUser', 'id','friend_user_id')->first();

    }
}

Controller

$frienduser= Auth::user()->friends()->where('friend_id','=','2')->first()->frienduser();
 $frienduser->isaccepted=1;
 $frienduser->save();