3-Way Relationships with Laravel Nova

Displaying the contents of the intermediate pivot Table Model in Laravel Nova.March 12, 2021

In some cases you may have a 3-Way Pivot table where you wan't to display only the related records in the Resource Show page.

Imagine having a database structure like below:

rooms
    id - integer
    number - string

reservation
    id - integer
    number - string

guest
    id - integer
    name - string

room_reservation_guest
    reservation_id - integer
    room_id - integer
    guest_id - integer

where you want to display the guests with their room number in the reservation show page like below.

Reservation Show Page

In order to achieve this you will need to define a custom intermediate Table Model and it's belongsTo method.

In our case:

namespace App; use Illuminate\Database\Eloquent\Relations\Pivot; class RoomReservationGuest extends Pivot { public function reservation() { return $this->belongsTo(Reservation::class); } public function guest() { return $this->belongsTo(Guest::class); } public function room() { return $this->belongsTo(Room::class); } }

Next in the Reservation Model define a function which will return the intermediate table model.

public function roomGuests() { return $this->hasMany(RoomReservationGuest::class); }

After create a Nova resource for the RoomReservationGuest model and define it's fields.

public function fields(Request $request) { return [ BelongsTo::make('Guest', 'guest', Guest::class), BelongsTo::make('Room', 'room', Room::class), ]; }

Last define a HasMany field in the Reservation resource for the RoomReservationGuest relation.

public function fields(Request $request) { return [ // ... HasMany::make('Guests', 'roomGuests', RoomReservationGuest::class), ]; }