Лучший способ запросить отношения модели в Eloquent - PullRequest
0 голосов
/ 12 июля 2020

Я работаю в контроллере в приложении Laravel. Я возвращаю стол в представление. Таблица основана на моей модели PlanSubmission. Я получаю параметры через запрос GET и использую эти параметры для возврата отфильтрованного набора строк в свое представление.

Первая часть моего контроллера выглядит так и работает нормально:

public function index()
    {

    //Used for filter.  The request is received in the URL
    if (request()->has('status')) {
        $plans = PlanSubmission::where('status', request('status'))->paginate(25)->appends('status', request('status'));
    }
    elseif (request('employer_name')) {
        $plans = PlanSubmission::where('employer_name', request('employer_name'))->paginate(25)->appends('employer_name', request('employer_name'));
        }

Я столкнулся с проблемой, потому что теперь мне нужно использовать отношения модели в контроллере. Я получаю из запроса "имя_ советника". Столбец "Advisor_id" - это внешний ключ в модели PlanSubmission. Столбец "Advisor_name" существует в модели Advisor. У меня есть функция в моей модели PlanSubmission, которая выглядит следующим образом:

    public function advisor()
{
    return $this->belongsTo(Advisor::class);
}

Первоначально я подумал, что есть способ сделать это легко с помощью чего-то вроде:

            $plans = PlanSubmission::where(advisor->name, request('advisor_name'))->paginate(25)->appends('advisor_name', request('advisor_name'));

Конечно, это не сработает, потому что я не могу ввести отношение в первый параметр в предложении Where.

Я не знаю, куда отсюда go. Другая моя мысль - сначала вернуть всех советников из модели советника следующим образом:

            $advisors = Advisor::where('name', request('advisor_name'));

Тогда, я полагаю, мне придется как-то l oop через это и получить идентификатор (первичный ключ) для каждого из объектов в $ Advisors и каким-то образом передать его в предложение PlanSubmission where. Я совершенно потерялся.

Ответы [ 2 ]

0 голосов
/ 12 июля 2020

Как Виктор упоминает в своем ответе, вы можете использовать whereHas вот так:

PlanSubmission::whereHas('advisor', function ($query) {
    $query->where('name', request('advisor_name'));
});

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

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

public function index()
{
   $query = PlanSubmission::where('something', 42);
   
   if (request()->has('status')) {
       $query = $query->where('status', request('status'));
   } elseif (..) {
     ...
   }

   return $query->paginate(25);
}

Другой способ выполнения условных запросов в Laravel - использовать when. Например, для статуса:

$query = $query->when(request->has('status'), function ($query) {
    // note that you don't have to return the query
    $query->where('status', request('status'));
});

// or PlanSubmission::>when(..)

В вашем примере вы не можете одновременно фильтровать по status И advisor_name, но давайте предположим, что это будет нормально, тогда вы можете объединить все следующим образом:

public function index()
{
   return PlanSubmission::query()
       //->where('something', 42)
       ->when(request->has('status'), function ($query) {
           $query->where('status', request('status'));
       })
       ->when(request->has('advisor_name'), function ($query) {
           $query->whereHas('advisor', function ($query) {
               $query->where('name', request('advisor_name'));
           });
       })->paginate(25);
}

Этот подход может показаться многословным для простых запросов, и тогда можно использовать if условия, но для сложных запросов when может быть полезным. Также в этой ситуации хорошо работает идея «создания запроса». Вы можете передавать построитель запросов и непрерывно его наращивать.

0 голосов
/ 12 июля 2020

Вы можете использовать whereHas для этого

docs

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