Опрос отдаленных отношений - PullRequest
1 голос
/ 31 марта 2019

У меня есть три таблицы: users, accounts и hotels. Пользователи и учетные записи связаны с отношением belongstoMany, а учетные записи и отели связаны одинаково.У каждого пользователя есть учетные записи, а в этих учетных записях есть отели.

Когда у меня есть Auth::user(), как я могу вернуть все отели?

$accounts = Auth::user()->accounts()->get();

С помощью приведенного выше заявления я могу получить все учетные записи.Как я могу вернуть все отели?

ЧТО Я ПОПРОБОВАЛ?

public function index(Request $request)
    {
        $accounts = Auth::user()->accounts()->get();
        $hotels = collect();
        foreach ($accounts as $key => $a) {

            $h = $a->hotels();
            $hotels = $hotels->toBase()->merge($h);

                }
            dd($hotels);
        return view('hotels.index',compact('hotels'));

    }

, но этот код не возвращает мне коллекцию отелей, которую я могу использовать в файлах просмотра лезвия

1 Ответ

3 голосов
/ 31 марта 2019

Случай 1

В случае, если у вас есть отношения, как показано на диаграмме ниже

user accounts hotels relationship

Что вы ищетеэто отношение hasManyThrough.

Из документации Laravel

Отношение «есть много через» обеспечивает удобный ярлык для доступа к удаленным отношениям черезпромежуточное отношение

В вашем случае для вашей модели User вы можете определить отношение

public function hotels()
{
  return $this->hasManyThrough('App\Hotel', 'App\Account');
}

Чтобы затем получить свою коллекцию отелей, вы можете просто использовать

$hotels = Auth::user()->hotels;

Вы также можете предоставить дополнительные аргументы для функции hasManyThrough, чтобы определить ключи, используемые в каждой таблице, отличные примеры этого приведены в документации, указанной выше!

Случай 2

Если вместо этого у вас есть отношение, как показано на следующей диаграмме

distant many-to-many relation

Это немного сложнее (или, по крайней мере,Менее чистый).Лучшее решение, которое я могу придумать, использующее наименьшее количество запросов, - это использовать with.

$accounts = Auth::user()->accounts()->with('hotels')->get();

. Он предоставит вам набор учетных записей, каждый с дочерним элементом hotels.Теперь все, что нам нужно сделать, это получить отели как отдельную коллекцию, это просто с некоторыми аккуратными функциями сбора, предоставляемыми Laravel.

$hotels = $accounts->flatMap(function($account) {
  return $account->hotels;
})->unique(function ($hotel) {
  return $hotel->id;
});

Это сделает работу по созданию коллекции отелей.На мой взгляд, было бы чище и эффективнее просто создать новые отношения, как показано ниже.

a simpler many-to-many relationship

А затем выполнять запросы, используя базовые методы Eloquent.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...