Получить коллекцию элементов отношений через несколько отношений в Laravel - PullRequest
0 голосов
/ 14 сентября 2018

У меня есть следующие отношения:

  • Users имеют полиморфные отношения многие ко многим (morphedByMany) с Customers, Locations и Vendors.
  • Customers, Locations и Vendors каждый имеет hasMany или hasManyThrough отношения с Datasets.

Я бы хотел получить Datasets, к которому данный User имеет доступ через свои отношения. Кроме того, некоторые наборы данных через различные отношения могут быть одинаковыми, поэтому я хочу уникальный список.

Я создал следующий метод для моей User модели, которая работает правильно (на основе Laravel получает коллекцию элементов отношений ):

public function accessibleDatasets()
{
    $datasetsByCustomers = $this->customers()->with('datasets')->get()->pluck('datasets')->flatten();
    $datasetsByLocations = $this->locations()->with('datasets')->get()->pluck('datasets')->flatten();
    $datasetsByVendors   = $this->vendors()->with('datasets')->get()->pluck('datasets')->flatten();

    $datasets            = $datasetsByCustomers;
    $datasets            = $datasets->merge($datasetsByLocations);
    $datasets            = $datasets->merge($datasetsByVendors);

    return $datasets->unique();
}

Есть ли "правильный путь" или более эффективный способ получить это (кроме использования некоторой функции приведения для слияний)? Является ли загрузка моделей, а затем выравнивание лучше? Связанные значения не будут меняться слишком часто, поэтому я могу кэшировать результаты, но хотел получить некоторую обратную связь.

1 Ответ

0 голосов
/ 15 сентября 2018

Наиболее эффективным способом было бы выполнение одного запроса к базе данных, как уже упоминал Тим.

Так как вы можете кэшировать результаты и хотите сэкономить несколько строк кода, я бы лучше сделал:

public function accessibleDatasets()
{
    $this->load('customers.datasets', 'locations.datasets', 'vendors.datasets');

    return $this->customers->flatMap->datasets
        ->merge($this->locations->flatMap->datasets)
        ->merge($this->vendors->flatMap->datasets);
}

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

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