Nested controllers is a new feature in Laravel 5 and is used to handle all of the RESTful actions that deal with relationships. For example, we can take advantage of this feature for the relationship between accommodations and rooms.
The relationship between accommodation and room is as follows:
In our models, we will now write the code to enable the one-to-one and one-to-many relationships to be skillfully handled by Laravel.
First, we will add the code that is needed by the Accomodation.php
file that represents the accommodation
model as follows:
class Accommodation extends Model { public function rooms(){ return $this->hasMany('MyCompanyAccommodationRoom'), } }
The rooms()
method creates an easy way to access the relationship from inside the accommodation model. The relation states that "the accommodation hasMany rooms". The hasMany
function, when residing inside the Accommodation
class, without any additional parameters, expects a column named accommodation_id
to exist in the Room
model's table, which in this case is rooms
.
Now, we will add the code that is needed by the Room.php
file that represents the Room
model:
class Room extends Model { public function accommodation(){ return $this->belongsTo('MyCompanyAccommodation'), } }
This code states that "a room belongsTo an accommodation". The belongsTo method inside the Room
class, without any additional parameters, expects a field in the room
model's table; in this case, rooms
, named accommodation_id
.
The command to create a nested controller is as follows:
$php artisan make:controller AccommodationsRoomsController
Then, the following line would be added to the app/Http/routes.php
file:
Route::resource('accommodations.rooms', 'AccommodationsRoomsController'),
To display the routes created, the following command should be executed:
$php artisan route:list
The following table lists the HTTP verbs and their functions:
HTTP verb |
Function |
URL | |
---|---|---|---|
1 |
|
This shows the accommodation and room relations |
|
2 |
|
This shows an accommodation and room relation |
|
3 |
|
This creates a new accommodation and room relation |
|
4 |
|
This entirely modifies (updates) an accommodation and room relation |
|
5 |
|
This partially modifies (updates) an accommodation and room relation |
|
6 |
|
This deletes an accommodation and room relation |
|
A nice mechanism used to illustrate an Eloquent relation directly inside the controller is performed through the use of a nested relation, where two models are connected firstly through the route and secondly through their controller method's parameters via model dependency injection.
Let's investigate the update
/modify PUT
nested controller command. The URL looks like this: http://www.hotelwebsite.com/accommodations/21/rooms/13
.
Here, 21
would be the ID of the accommodation and 13
would be ID of the room. The parameters are the type-hinted models. This allows us to easily update the relationship as follows:
public function update(Accommodation $accommodation, Room $room) { $room->accommodation()->associate($accommodation); $room->save(); }
Similarly, it is easy to perform the nested create
operation with a POST
body to http://www.hotelwebsite.com/accommodations/21/rooms
. The POST
body is a JSON formatted object:
{"roomNumber":"123"}
Note that there is no ID needed for the room since we are creating it:
public function store(Accommodation $accommodation) { $input = Input::json(); $room = new Room(); $room->room_number = $input->get('roomNumber'), $room->save(); $accommodation->rooms()->save($room); }