Laravel 5.4 выщипывает, где

Я работаю над системой распределения новостей по радио. Пытаюсь вернуть просмотр всех заданий для конкретного выпуска новостей, и я в тупике.

Таблицы
таблица пользователей

 id | name
 ---|-------
  1 | Admin
  2 | Susan
  3 | Ed
  4 | Jen

таблица выпусков новостей

 id | forStation_id | name
 ---|---------------|-----
  1 |       1       | AM
  2 |       1       | PM
  3 |       2       | Sports

таблица станций

 id | calls
 ---| -----
  1 | JNDV
  2 | YXWQ

таблица назначений

 id | anchorId | newscastId |  startDate  |   endDate   | isTemp
 ---|----------|------------|-------------|-------------|--------
  1 |     2    |     1      | 01 May 2017 | 31 Dec 2999 |
  2 |     3    |     1      | 02 May 2017 | 06 May 2017 |  True
  3 |     4    |     2      | 01 Apr 2017 | 31 Dec 2999 |
  4 |     3    |     3      | 01 Apr 2017 | 28 Apr 2017 |

(часть) модели назначения

public function anchor()
{
    return $this->belongsTo(User::class, 'anchor_id')->withTrashed();
}

public function cast()
{
    return $this->belongsTo(Newscast::class, 'cast_id')->withTrashed();
}

(часть) модели выпуска новостей

public function for_station()
{
    return $this->belongsTo(Station::class, 'for_station_id')->withTrashed();
}

function getNameInputStationAttribute() {
    return $this->for_station->calls . "-" . $this->name_input;
}

(часть) контроллера назначения

/**
 * Display all Assignments for one input name.
 *
 * @param  int  $name
 * @return \Illuminate\Http\Response
 */
public function showAssignmentsByCastName($castName)
{
    if (! Gate::allows('assignment_view')) {
        return abort(403);
    }
    $relations = [
        'anchors' => \App\User::get()->pluck('name', 'id'),
        'casts' =>  \App\Newscast::with('for_station')->get()->pluck('name_input_station', 'id'),
        'assignments' => \App\Assignment::with('cast')->get(),
    ];

dump($relations);

return view('assign.list', compact('castName') +$relations);
}

Как и следовало ожидать, этот код возвращает полную коллекцию assignments.

Вывод

  Anchor  | Cast Name   | Start Date  |   End Date
 ---------|-------------|-------------|-------------
  Susan   | JNDV-AM     | 01 May 2017 | 31 Dec 2999
  Ed      | JNDV-AM     | 02 May 2017 | 06 May 2017
  Jen     | JNDV-PM     | 01 Apr 2017 | 31 Dec 2999
  Ed      | YXWQ-Sports | 01 Apr 2017 | 28 Apr 2017

Я пробовал несколько способов ограничить назначения только одним newscastId, но пока безуспешно.

Желаемый результат для /assignment/list/JNDV-AM 1 мая 2017 г.

  Anchor  | Cast Name   | Start Date  |   End Date
 ---------|-------------|-------------|-------------
  Susan   | JNDV-AM     | 01 May 2017 | 31 Dec 2999
  Ed      | JNDV-AM     | 02 May 2017 | 06 May 2017

Краткосрочное назначение является временным (isTemp=True). В те дни, когда он действителен, он должен быть указан сверху.

Желаемый результат для /assignment/list/JNDV-AM со 2 мая по 6 мая 2017 г.

  Anchor  | Cast Name   | Start Date  |   End Date
 ---------|-------------|-------------|-------------
  Ed      | JNDV-AM     | 02 May 2017 | 06 May 2017
  Susan   | JNDV-AM     | 01 May 2017 | 31 Dec 2999

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

Основной вопрос Какие изменения нужно внести в
'assignments' => \App\Assignment::with('cast')->get(),
, чтобы получать только назначения для JNDV-AM (newscastId = 1)?

Расширенный вопрос Как вы рекомендуете изменить relations, чтобы возвращались только текущие и будущие назначения для JNDV-AM, сегодняшнее назначение в первую очередь, с наименьшим возможным количеством запросов?


person Scott Roberts    schedule 01.05.2017    source источник


Ответы (2)


Вы можете передать функцию в свой оператор with:

'assignments' => \App\Assignment::with(['cast' => function ($query) {
    $query->where('newscastId', '=', 1);
}])->get()
person Alex Harris    schedule 01.05.2017
comment
Это один из нескольких способов вернуть только JNDV-AM (newscastId=1), но он не работает, когда я пытаюсь просмотреть назначения для JNDV-PM (newscastId=2). Ключ к тому, что я ищу, заключается в том, как получить доступ к newscastId, когда я использовал имя выпуска новостей для выполнения запроса. Хм ... это породило идею ... Я попробую эту идею и опубликую результаты. - person Scott Roberts; 01.05.2017
comment
На самом деле этот код выдавал странный результат... первые две строки представления были правильным элементом, но имя в последней строке было пустым. - person Scott Roberts; 01.05.2017

Вот рабочий код, который я придумал:

(часть) контроллера назначений

public function showAssignmentsByCastName($calls, $name_input)
{
    if (!Gate::allows('assignment_view')) {
        return abort(403);
    }

    $castName = strtoupper($calls). "-" . $name_input;
    $station_id = \App\Station::where('calls', $calls)->get();
    $station = \App\Station::findOrFail($station_id);

    $cast_id = \App\Newscast::where([
        ['for_station_id', $station->id],
        ['name_input', $name_input]
    ])->get();
    $cast = \App\Newscast::findOrFail($cast_id);

    $relations = [
        'anchors' => \App\User::get()->pluck('name', 'id'),
        'casts' => \App\Newscast::where('cast_id', $cast->id),
        'assignments' => \App\Assignment::where('cast_id', $cast->id)->get(),
    ];
    return view('assign.list', compact('castName') + $relations);
}

веб-маршрут

Route::get('assign/{calls}-{name_input}', 'AssignmentsController@showAssignmentsByCastName')->name('assign.list');
person Scott Roberts    schedule 02.05.2017