Laravel красноречивые отношения и сводные таблицы - PullRequest
1 голос
/ 07 марта 2020

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

пользователи

  • id *
  • ...

команды

  • id *
  • ...

team_user

  • team_id *
  • user_id *
  • isLeader
  • подтверждено

Как видите, пользователь может быть частью количество команд, и * он также может быть назначен лидером данной команды. У команды может быть несколько лидеров.

Модель пользователя имеет следующие отношения:

// Returns all the teams connected to the user and where the confirmed timestamp is set
public function teams()
{
    return $this->belongsToMany(Team::class)->wherePivot('confirmed', '!=', null);
}
// Returns all the teams where the user is appointed team leader
public function teamleaderTeams()
{
    return $this->belongsToMany(Team::class)->wherePivot('isLeader', '=', 1);
}

Команда имеет:

public function confirmedUsers()
{
    return $this->belongsToMany(User::class)->where('confirmed', '!=', null);
}

Мне нужно что-то, что возвращает все пользователи, для которых пользователь является лидером команды. Так что, если вы не являетесь лидером команды, результат будет, конечно, пустым, но если вы таковым, он должен вернуть всех пользователей из всех команд, в которых вы назначены лидером.

Я попытался спросить вокруг, и получил некоторые предложения, но на самом деле не пришли к решению. Я действительно понимаю, чего хочу (я думаю). Оооо ... так как вы можете сказать, для каких команд пользователь является лидером команды через отношение teamleaderTeams (), я могу l oop через каждую, а затем попросить всех подтвержденных пользователей получить через отношение подтвержденный пользователи (). Но мне только удалось выполнить 1055 * это в контроллере, и это только кажется грязным.

Т.е. это только приводит к сбою браузера (кажется, что оно бесконечно l oop или что-то в этом роде, и я не совсем понимаю, почему).

public function getLeaderForAttribute()
{
        $users = collect();
        foreach($this->teamleaderTeams as $team)
        {
            foreach ($team->confirmedUsers as $user) {
                $users->add($user);
            }
        }
        return $users->unique('id');
}

В любом случае, у любого есть хорошее решение для отношения teamleaderUsers () (не очень хорошее название для него), которое возвращает всех пользователей из всех команд, для которых данный пользователь является лидером команды ( это полный рот)?

Ответы [ 2 ]

1 голос
/ 08 марта 2020

Я думаю, что сейчас хорошее время для использования моделей Pivot. Вы можете определить сводную модель, расширив класс Pivot. Кроме того, вы можете определить отношения в сводной модели. Итак, если у вас есть отношение users в вашей сводной модели, вы можете сделать запрос следующим образом:

TeamUser::with('users')->where('isLeader', 1); // If the pivot model is called TeamUser

Конечно, вы можете исключить указанного c пользователя как обычно:

TeamUser::with(['users' => function($query) {
    $query->where('id', '<>', 1); // If we want to exclude user with id 1
}])
->where('isLeader', 1);

Конечно, вы также можете сделать дополнительное условие where в отношении:

public function teamLeaders()
{
    return $this->hasMany('users')->where('isLeader', 1);
}

Пожалуйста, прочитайте больше об этом здесь , а вот API

Удачи!

1 голос
/ 07 марта 2020

Во-первых, у вас есть опечатка здесь:

$users->add($user);

Это должно быть Коллекция :: pu sh:

$users->push($user);

Во-вторых, я думаю Ваш подход в порядке. Однако, если производительность становится вашей проблемой, вы можете написать собственный запрос для оптимизации, а не зависеть от Laravel ORM.

В-третьих, вы можете назвать отношения следующим образом: leadingTeams вместо teamleaderTeams и leadingUsers вместо teamleaderUsers.

...