I'm working on an assignment system for radio newscasts. Trying to return a view of all assignments for a particular newscast, and I'm stymied.
Tables
users table
id | name
---|-------
1 | Admin
2 | Susan
3 | Ed
4 | Jen
newscasts table
id | forStation_id | name
---|---------------|-----
1 | 1 | AM
2 | 1 | PM
3 | 2 | Sports
stations table
id | calls
---| -----
1 | JNDV
2 | YXWQ
assignments table
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 |
(part of) Assignment model
public function anchor()
{
return $this->belongsTo(User::class, 'anchor_id')->withTrashed();
}
public function cast()
{
return $this->belongsTo(Newscast::class, 'cast_id')->withTrashed();
}
(part of) Newscast model
public function for_station()
{
return $this->belongsTo(Station::class, 'for_station_id')->withTrashed();
}
function getNameInputStationAttribute() {
return $this->for_station->calls . "-" . $this->name_input;
}
(part of) Assignment controller
/**
* 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);
}
As I'd expect, this code returns the full collection of assignments
.
Output
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
I've tried several ways to limit the assignments to only one newscastId
, thus far without success.
Desired Output for /assignment/list/JNDV-AM on 01 May 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
The shorter-term assignment is a temporary one (isTemp=True). During the days it is valid, it should be listed on top.
Desired Output for /assignment/list/JNDV-AM on 02 May 2017 through 06 May 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
I'm modifying code produced by an admin panel generator tool. It seems to me that querying for all users and all casts is not the most efficient way to go about it. I'd think, since I'm looking for only the current & future assignments for one newscast, that the anchors
and casts
relations should be filtered.
Basic question
What changes should I make to
'assignments' => \App\Assignment::with('cast')->get(),
to get only the assignments for JNDV-AM (newscastId = 1)?
Advanced Question
How do you recommend changing relations
to return only the current and future assignments for JNDV-AM, today's assignment first, with the fewest queries possible?
Here is the working code I came up with:
(part of) Assignments controller
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);
}
web route
Route::get('assign/{calls}-{name_input}', 'AssignmentsController@showAssignmentsByCastName')->name('assign.list');