1

Тема: Laravel 5.8. Болюче питання про залежності

Всім привіт! З горем навпіл я розібрався із залежностями Eloquent, але, як показує практика, не до кінця.

Словом, є отака структура даних: https://ibb.co/0G61301

Таблиці files і compositions, а також таблиці files і categories зв'язані між собою методом many-to-many за допомогою pivot-таблиць.

Що потрібно: вивести усі композиції вибраної категорії. Я це пробую зробити отак:

public function showCategory($slug)
    {
        $category = Category::where('slug', $slug)->first();
        $files = $category->files;
        foreach ($files as $file) {
            $compositions = $file->compositions;
            foreach ($compositions as $composition) {
                echo $composition->name . '<br />';
            }
        }
    }

Проблема в тому, що якщо кілька різних файлів прив'язані до однієї композиції, то в переліку ця композиція показується кілька разів. Я вже пробував видалити дублі за допомогою PHP-функції array_unique(), але тоді викидає помилку:

array_unique() expects parameter 1 to be array, object given

Переважно я стараюся сам розв'язати проблему, але в даному випадку я застряг уже на кілька днів, тому прошу допомоги. Наперед вдячний за будь-які відповіді!

2 Востаннє редагувалося ivaniura (12.04.2019 19:01:16)

Re: Laravel 5.8. Болюче питання про залежності

Поки чекав відповіді, розв'язав проблему самотужки  :)

Просто додав ще один масив $composition_list, у який вношу значення із циклу foreach із перевіркою на наявність ідентичного значення у масиві — якщо запис вже існує, то вдруге він у масив не додається.

foreach ($files as $file) {
    $compositions = $file->compositions;
    $composition_list = array();
    foreach ($compositions as $composition) {
        if(!in_array($composition, $composition_list)) {
            $composition_list[] = $composition;
        }
    }
}

UPD. Наразі доданий масив не приносить користі. Всередині циклу він кожного разу перезаписується, а якщо винести його назовні, то дані все одно дублюються. Тож я ще в пошуках та в надії на допомогу...

UPD2. Створив ще один цикл, в одному перевіряю наявність дубльованих id, в інший записую готовий результат (оскільки з одним масивом php попереджував мене, що я намагаюся об'єкт перетворити на рядок).

$files = $category->files;
$composition_ids = array();
$composition_list = array();
foreach ($files as $file) {
    $compositions = $file->compositions;
    foreach ($compositions as $composition) {
        if(!in_array($composition->id, $composition_ids)) {
            $composition_ids[] = $composition->id;
            $composition_list[] = $composition;
        }
    }
}

Готовий масив для використання у blade - composition_list.

Тепер ніби все працює, але щось мені здається, що прикол зі створенням двох додаткових масивів — великі незручні граблі, які можна замінити елегантнішим варіантом. Наразі залишаю, як є, але сподіваюся, що тут хтось щось та й підкаже з часом.

3 Востаннє редагувалося Oleshko (20.05.2019 14:51:47)

Re: Laravel 5.8. Болюче питання про залежності

Добрий день, можливо трохи запізно, але кілька зауважень. Коли ви використовуєте eager loading обовязково використовуйте метод with, так як це породжує n+1 проблему(про це можете в гугл пошукати).
Приклад:
$category = Category::with('files')->where('slug', $slug)->first();
Також в методі with ви можете підключити звязки звязків
Приклад:
$category = Category::with( 'files.compositions')->where('slug', $slug)->first();
Після цього у вас буде обєкт категорій з файлами і композиціями і не буде необхідності використовувати цикли, що є не найкращим рішенням

4

Re: Laravel 5.8. Болюче питання про залежності

Не зрозуміло чому не використали поліморф.