Я работаю над реализацией дружбы в своем проекте, но в дополнение только к добавлению друзей, мне бы хотелось иметь функцию приглашения, как в Facebook, я использую самозависимый подход "многие ко многим",
pivotсхема таблицы:
Schema::create('user_friends', function (Blueprint $table) {
$table->primary(['user_id', 'friend_id']);
$table->unsignedInteger('user_id');
$table->unsignedInteger('friend_id');
$table->timestamps();
$table->timestamp('accepted_at')->nullable()->default(null);
$table->timestamp('refused_at')->nullable()->default(null);
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
$table->foreign('friend_id')
->references('id')->on('users')
->onDelete('cascade');
});
Я делю друзей / будущих друзей на 3 группы:
- Друзья, которые были подтверждены, и эта категория, включая друзей, которых я приглашаю, и друзейприглашающие меня;
- Приглашенные: те, кого я приглашаю, но не одобрил;
- Приглашающие: те, кто приглашает меня, но я пока не говорю да.
Нижеих соответствующий код:
Группа 1: друзья:
class User {
//
/**
* Friendships that started by the user
*/
public function friendsOfMine()
{
return $this->belongsToMany('App\User', 'user_friends', 'user_id', 'friend_id')
->withPivot(['accepted_at', 'refused_at'])
->wherePivot('accepted_at', '<>', null)
->withTimestamps();
}
/**
* Friendships that started by others
*/
public function friendOfOthers()
{
return $this->belongsToMany('App\User', 'user_friends', 'friend_id', 'user_id')
->withPivot(['accepted_at', 'refused_at'])
->wherePivot('accepted_at', '<>', null)
->withTimestamps();
}
// accessor allowing you call $user->friends
public function getFriendsAttribute()
{
if (!array_key_exists('friends', $this->relations)) {
$this->loadFriends();
}
return $this->getRelation('friends');
}
protected function loadFriends()
{
if (!array_key_exists('friends', $this->relations)) {
$friends = $this->mergeFriends();
$this->setRelation('friends', $friends);
}
}
protected function mergeFriends()
{
return $this->friendsOfMine->merge($this->friendOfOthers);
}
Группа 2: Приглашенные:
/**
* Users that are invited as friends by this user.
*/
public function invitees()
{
return $this->belongsToMany('App\User', 'user_friends', 'user_id', 'friend_id')
->withPivot(['accepted_at', 'refused_at'])
->wherePivot('accepted_at', null)
->withTimestamps();
}
Группа 3: Приглашающие:
/**
* Users that invite this user as friend.
*/
public function invitors()
{
return $this->belongsToMany('App\User', 'user_friends', 'friend_id', 'user_id')
->withPivot(['accepted_at', 'refused_at'])
->wherePivot('accepted_at', null)
->withTimestamps();
}
и затем, когда я хочу пригласить нового пользователя, я хочу убедиться, что этот новый пользователь не принадлежит к этим 3 группам:
public function inviteFriend(User $user)
{
if (!$this->is($user) &&
!$this->friends->contains($user) &&
!$this->invitees->contains($user) &&
!$this->invitors->contains($user)) {
$this->invitees()->attach($user);
}
}
Тогда возникает странная проблема, я использовалdd () для проверки хода выполнения и подтверждения того, что условие выполнено и
$this->invitees()->attach($user);
был выполнен, но, однако, $ user не был добавлен правильно, но если я уберу эту самую одну проверку состояния (не другую)
!$this->invitees->contains($user)
ифункция становится
public function inviteFriend(User $user)
{
if (!$this->is($user) &&
!$this->friends->contains($user) &&
// !$this->invitees->contains($user) &&
!$this->invitors->contains($user)) {
$this->invitees()->attach($user);
}
}
Тогда это будет работать нормально, но, тем не менее, можно будет неоднократно приглашать одного и того же человека и затем вызывать нарушение SQL-ограничения.
Любой может помочь мнеэтого?Заранее спасибо !!!