Laravel Nova: Limiting BelongsToMany options

    More things you can do when extending Laravel Nova resources

    09 Feb 2020 • Last updated a few seconds ago

    For a project I'm working on I want to assign multiple Rooms to Reservations. This is easy using a BelongsToMany field in Laravel Nova.

    app/Nova/Reservation.php










     




    namespace App\Nova;
    
    use Laravel\Nova\Fields\BelongsToMany;
    
    class Reservation extends Resource
    {
    	public function fields(Request $request)
        {
            return [
    			BelongsToMany::make('Rooms')
    		];
    	}	
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    But what if you only want to display rooms that are not occupied?

    If you have read my other post about Showing more details in a BelongsTo field, you might know where I'm going with this.

    Step 1: Extend your Room Nova resource

    And write a custom relatableQuery

    app/Nova/Helpers/AvailableRoom.php







     










     
     
     
     
     
     
     
     
     
     
     


    namespace App\Nova\Helpers;
    
    use App\Nova\Room;
    use App\Reservation;
    use Laravel\Nova\Http\Requests\NovaRequest;
    
    class AvailableRoom extends Room
    {
    
        public static $globallySearchable = false;
        public static $displayInNavigation = false;
    
        public static function uriKey() :string
        {
            return Room::uriKey();
        }
       
        public static function relatableQuery(NovaRequest $request, $query)
        {
    		// the reservation we're trying to attach a room to...
    		$reservation = $request->findModelOrFail();
    		
    		// use some code to find and fill $occupied_room_ids based on $reservation
    		$occupied_room_ids = []; // write your own logic...
            
            // return all rooms that are not occupied
            return  $query->whereNotIn('id', $occupied_room_ids);
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29

    Step 2: Use this extended resource in your BelongsToMany field

    app/Nova/Reservation.php











     
     




    namespace App\Nova;
    
    use Laravel\Nova\Fields\BelongsToMany;
    use App\Nova\Helpers\AvailableRoom;
    
    class Reservation extends Resource
    {
    	public function fields(Request $request)
        {
            return [
    			BelongsToMany::make('Rooms', 'rooms', AvailableRoom::class)
                    ->help('Only available rooms are shown.'),
    		];
    	}
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    That's really all there is to it! 🎉