'Elegant way to create M:N relationships between the same models in Laravel?
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?
Solution 1:[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();
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
