Система дружбы с Laravel :Отношения " многие ко многим"

StackOverflow https://stackoverflow.com//questions/25049753

  •  21-12-2019
  •  | 
  •  

Вопрос

Я пытаюсь создать систему дружбы с Laravel (я начинаю с этого), но у меня заблокированы отношения.Дело вот в чем :существует одна таблица Users и одна таблица Friends, которая содержит следующие столбцы :

friends: id, user_id, friend_id, accepted.

Это выглядит как "Много ко многим", поэтому вот что я установил для пользовательского класса :

class User extends Eloquent {
    function friends()
    {
        return $this->belongsToMany('User');
    }
}

Но когда я пытаюсь :

$friends = User::find($id)->friends()->get()

У меня такая ошибка :

Base table or view not found: 1146 Table 'base.user_user' doesn't exist

Я хотел бы получить список друзей пользователя, независимо от того, отправил ли пользователь приглашение или получил его.Таким образом, пользователь может использовать user_id или friend_id, а затем я извлекаю данные другого пользователя в зависимости от этого столбца.

Есть какие-нибудь идеи?Спасибо!

Редактировать :Вот код, который я использую :

$usersWithFriends = User::with('friendsOfMine', 'friendOf')->get();
$user = User::find(Auth::id())->friends;

foreach($user as $item) {
    echo $item->first()->pivot->accepted;
} 
Это было полезно?

Решение

TLDR;Вам нужно 2 перевернутых отношения, чтобы сделать его работать, проверять настройку и использование ниже


сначала с ошибка - вот как следует выглядеть ваше отношение:

function friends()
{
  return $this->belongsToMany('User', 'friends', 'user_id', 'friend_id')
    // if you want to rely on accepted field, then add this:
    ->wherePivot('accepted', '=', 1);
}
.

Тогда он будет работать без ошибок:

$user->friends; // collection of User models, returns the same as:
$user->friends()->get();
.


Настройка

<Сильные> Однако Вы хотели бы, чтобы отношение к работе в обоих направлениях.Красноречивый не обеспечивает отношение такого рода, поэтому вы можете вместо этого можно использовать 2 перевернутых отношения и объединить результаты :

// friendship that I started
function friendsOfMine()
{
  return $this->belongsToMany('User', 'friends', 'user_id', 'friend_id')
     ->wherePivot('accepted', '=', 1) // to filter only accepted
     ->withPivot('accepted'); // or to fetch accepted value
}

// friendship that I was invited to 
function friendOf()
{
  return $this->belongsToMany('User', 'friends', 'friend_id', 'user_id')
     ->wherePivot('accepted', '=', 1)
     ->withPivot('accepted');
}

// 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->friendOf);
}
.

Использование

С такой настройкой вы можете сделать это:

// access all friends
$user->friends; // collection of unique User model instances

// access friends a user invited
$user->friendsOfMine; // collection

// access friends that a user was invited by
$user->friendOf; // collection

// and eager load all friends with 2 queries
$usersWithFriends = User::with('friendsOfMine', 'friendOf')->get();

// then
$users->first()->friends; // collection

// Check the accepted value:
$user->friends->first()->pivot->accepted;
.

Другие советы

Очевидно, что это проблема в вашей базе данных, а также в определении отношения.Тип отношения "Многие ко многим" предполагает, что вы будете использовать промежуточную таблицу.Вот что вам нужно сделать :

  1. Создать user_friend (id, user_id, fried_id) таблица в вашей схеме.
  2. Удалите ненужные поля из user и friend таблицы.
  3. Создайте соответствующие внешние ключи . user.id-> user_friend.user_id , friend.id -> user_friend.friend_id
  4. Лучше определить полное отношение на Пользователь и Друг Модели,

например :

 class User extends Eloquent {
    function friends()
    {
        return $this->belongsToMany('User', 'user_friend', 'user_id', 'friend_id');
    }
}

Вы можете прочитать гораздо больше в Laravel docs, ЗДЕСЬ

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top