Я работаю над небольшим laravel проектом, в котором пользователи могут добавлять друг друга в друзья. Моя сводная таблица выглядит так:
+----+---------+-----------+----------+------------+------------+
| id | user_id | friend_id | accepted | created_at | updated_at |
+----+---------+-----------+----------+------------+------------+
| 1 | 1 | 2 | 0 | NULL | NULL |
+----+---------+-----------+----------+------------+------------+
В этом случае пользователь 1 добавил пользователя 2 в качестве друга, но это работает двумя способами, поскольку оба пользователя могут отправлять запросы на добавление в друзья. Поскольку пользователь может как «иметь», так и «быть» другом, я объединяю две коллекции при получении друзей пользователя:
// friendship that I started
function primaryFriends()
{
return $this->belongsToMany('App\User', 'friends', 'user_id', 'friend_id');
}
// friendship that I was invited to
function secondaryFriends()
{
return $this->belongsToMany('App\User', 'friends', 'friend_id', 'user_id');
}
// Merged two collections
function friends()
{
return $this->primaryFriends->merge($this->secondaryFriends);
}
Вызов метода friends () успешно возвращает все дружеские отношения, но удаление дружбы заставило меня усомниться в моем методе. Представьте, что пользователь 1 хочет удалить пользователя 2 как друга. Их дружба может существовать двумя разными способами:
+----+---------+-----------+----------+------------+------------+
| id | user_id | friend_id | accepted | created_at | updated_at |
+----+---------+-----------+----------+------------+------------+
| 1 | 1 | 2 | 0 | NULL | NULL |
+----+---------+-----------+----------+------------+------------+
или:
+----+---------+-----------+----------+------------+------------+
| id | user_id | friend_id | accepted | created_at | updated_at |
+----+---------+-----------+----------+------------+------------+
| 1 | 2 | 1 | 0 | NULL | NULL |
+----+---------+-----------+----------+------------+------------+
Поэтому, когда я удаляю дружбу, я пытаюсь отделить обе возможные связи:
public function deleteFriend($friend_id)
{
$friend = User::find($friend_id);
$friend->primaryFriends()->detach(auth()->user());
auth()->user()->primaryFriends()->detach($friend);
}
Это работает, но я начинаю сомневаться в том, что это хорошая практика? Мне кажется, что есть менее сложный способ добиться этого?
Представьте, хочу ли я проверить, является ли пользователь другом. Обычно я бы сделал это так:
if($this->friends()->where('id', 'like', $user_id)->exists()) ...
Но поскольку метод friends () не возвращает коллекцию, как «ownstomany», я полагаю, я не могу сделать это таким образом? Следует ли мне проверять primaryFriends и SecondaryFriends по отдельности? Все это кажется слишком сложным. Может ли кто-нибудь уточнить, правильно ли я подхожу к этому? Заранее спасибо!