Laravel eloquent - проблемы с запросом отношения к собственности

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

Это то, что я пробовал. По-прежнему получаю предметы от других пользователей.

$categories = Category::parents()
                        ->with(['lineItems' => function ($query) use($id) {
                                $query->where('user_id', $id);
                            }])->get();

Не удалось найти ничего, что работает. (с использованием laravel 5.7)

Отношения

Категория

public function lineItems()
{
    return $this->hasMany(LineItem::class);
}

Позиции

public function category()
{
    return $this->belongsTo(Category::class);
}

public function user()
{
    return $this->belongsTo(User::class);
}

Какой результат вы получаете?

Varun.Kumar 26.10.2018 06:33

@ Varun.Kumar Я получаю все категории и все элементы строки, независимо от пользователя.

Shevy 26.10.2018 06:45

Можете ли вы включить ваши отношения с lineItems()?

Travis Britz 26.10.2018 06:45

@TravisBritz добавлен!

Shevy 26.10.2018 06:46

@Shevy, как вы получаете доступ к категориям $? Это не $categories->lineItems() (который бы повторно запускал запрос), не так ли? (обратите внимание на скобку)

Travis Britz 26.10.2018 06:55

Я перебираю лезвие. На уровне позиции: @foreach ($child->lineItems as $line) {{ $line->description}} @endforeach

Shevy 26.10.2018 07:09

Привет @Shevy! Не могли бы вы добавить \DB::enableQueryLog(); над вашим запросом. А затем добавьте dd(\DB::getQueryLog()); после вашего запроса. Тогда покажите нам его скриншот? Итак, мы увидим ваш SQL и посмотрим, что не так.

Makashov Nurbol 26.10.2018 07:17

@MakashovNurbol Я нашел решение, но не уверен, что оно лучшее. Это ниже. Ваше мнение?

Shevy 26.10.2018 07:25
0
8
66
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я не уверен, откуда берется метод ::parents() (нигде не могу найти документацию по нему; это что-то вы написали?), Но похоже, что

$categories = Category::all()
                      ->with(['lineItems' => function ($query) use ($id) {
                          $query->where('user_id', $id);
                     }])->get();

может работать?

Вы не можете цеплять всех (). get () занимает свое место при запросе. Родители () - это область действия. Он получает категории без родительского идентификатора.

Shevy 26.10.2018 06:59
Ответ принят как подходящий

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

Это запрашивает позиции дочерних и внучатых позиций.

$categories = Category::parents()->ordered()
                    ->with(['children.lineItems' => function($q) use($id) {
                        $q->where('user_id', '=', $id);
                    }, 'children.children.lineItems' => function($q) use($id) {
                        $q->where('user_id', '=', $id);
                    }])->get();

Ага, так было больше отношений, загружаемых лениво без ограничений. То, что у вас здесь, должно быть в порядке, если вы не планируете загружать больше уровней дочерних категорий. Если в итоге вы перейдете на 6 уровней, возможно, пришло время провести рефакторинг.

Travis Britz 26.10.2018 07:53

В моей версии вопроса они были у меня в to, но я понял, что на самом деле они мне не нужны. Это заставляет его стремиться, правда? @ travis-britz

Shevy 26.10.2018 08:02

Попробуй это:

$categories = Category::parents()
                        ->whereHas('lineItems', function ($query) use($id) {
                                $query->where('user_id', $id);
                        })->get();

Это получает только родительские категории, у которых есть lineItems. Ни у одной родительской категории нет lineItems, поэтому она ничего не возвращает.

Shevy 26.10.2018 16:08

В вашей структуре всего 2 уровня категории? Или он может иметь более двух уровней, например Транспортные средства -> Автомобили -> BMW -> 3.20d.

mutas 26.10.2018 18:05

в настоящее время в нем всего 3 уровня. Хотелось бы, чтобы он был больше и гибче.

Shevy 28.10.2018 16:08

Я понял, это сложнее, чем я думал. Но я могу предложить альтернативу, так что вы должны получить коллекцию LineItem с их отношением Category. Хотя это проще и выглядит более формально. И, возможно, вы можете сгруппировать по их категориям. Подводя итог, можно сказать, что начало запроса с LineItem :: выглядит лучше.

mutas 30.10.2018 12:29

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