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?