Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

lasse's avatar

Separation of concers

I'm making a booking system, with a getFreeRoomNumbers() method, does this method belong in the Hotel model or the Booking model?

How about a getAllBookedRoomNumbers() method?

0 likes
8 replies
ellenbrook's avatar

I would think that the relationship would be:

Hotel Model -> has many HotelRooms Hotel Room -> belongs to Hotel Booking -> references the hotel_id, hotel room_id (almost a pivot table with added columns?)

You're not booking a hotel, you're booking a hotel room, right? If that's the case I'd imagine your method would belong in the HotelRoom model, not Hotel.

1 like
lasse's avatar

Thanks for your answer! I've been thinking a bit more, and watched this Laracasts episodes: https://laracasts.com/lessons/controller-cleanup. I gave me the idea of placing all the functions to figure out which rooms are booked, which are reserved, which are free etc. in a separate BookingCreator model, how does that sound?

1 like
unitedworx's avatar

I would create a BookingHandler class which would be responsible for creating bookings, editing bookings, cancelling bookings, getting available units, getting reserved units etc etc.

If you app does not only handle room looking you could even abstract this booking handler so it will not only work with hotel rooms but also hotel facilities, villas, car hire, etc etc

1 like
lasse's avatar

Thanks once again for a great answer. I've been doing what you've said @unitedworx, but in my BookingHandler I then run into nasty dependencies like this:

public function allReservedRooms(Location $location)
{
$reservation = new Reservation;
return $reservation->allValid($location);
}

I can either pass the Reservation model to the allReservedRooms() method all the way from the BookingsController (through many other methods since allReservedRooms() is nested), or make the allValid() method static. Which way is better? Or is there a better way altogether? Thanks again for your suggestions.

xingfucoder's avatar

Hi @lasseal, I think that if you want later to extend your application to manage not only Rooms, but you may need manage HotelMeetingRooms you could create a generic function to manage and inject an interface IReservableLocation, then you make available by abstraction some new rooms or another Hotel places in your Hotel Management Application.

In your last function when you use the Location param could use the IReservableLocation.

Hope helps you.

uxweb's avatar

Hi @lasseal You can create a BookingRepository to store all related methods to booking:

class BookingRepository {

    public function findReservedRoomsForLocation(Location $location)
    {
        return "rooms";
    }

    public function book() {}

    public function findAvailableRooms() {}

}

Then you can inject this repository in the controller's constructor

class BookingsController {

    protected $bookingRepository;

    public function __construct(BookingRepository $bookingRepository)
    {
        $this->bookingRepository = $bookingRepository;
    }

    public function create()
    {
        $availableRooms = $this->bookingRepository->findAvailableRooms();

        return View::make('booking.create',  compact('availableRooms'));
    }
}

Hope this helps.

1 like
unitedworx's avatar

Hi @lasseal, What I do for my handlers or repositories is to create a facade so I can call it easily like BookingHandler::getAvailableRooms(); you are not calling static methos like this but things get resolved thought laravel IoC container so you can easily mock your facades if you do tests for your code or if you plan to later on.

you need a service provider to register your facade

<?php

use Illuminate\Support\ServiceProvider;

class BookingHandlerServiceProvider extends ServiceProvider {

    public function register()
    {
        $this->app['bookinghandler'] = $this->app->share(function($app
        {
            return new BookingHandler;
        });
    }
})

you need the facade itself


<?php use Illuminate\Support\Facades\Facade; class BookingHandlerFacade extends Facade { protected static function getFacadeAccessor() { return 'bookinghandler' } };

and you need to include the alias for you facade in app.php

 'aliases' => array(
      ....
      'BookingHandler' => 'BookingHandler',

      ///or if you use namespces
      'BookingHandler' => 'unitedworx\bookings\BookingHandler',

now you can easily call the booking handler via its facade anywhere in your code

i do this for all my handlers/repositories and it helps a lot and i know i can mock the facade later on if i want to write some tests

BookingHandler::getAvailableRooms();
1 like
lasse's avatar

@codebusiness Yes, more abstraction is certainly a good idea.

@uxweb: That is a neat solution which I used earlier, until I wanted to pass a listener from the BookingsController to my BookingHandler (like Jeffrey is doing around the 5:00 mark here: https://laracasts.com/lessons/controller-cleanup), which stops me from being able to instantiante my BookingHandler in my BookingsController. No luck finding a solution to both being able to inject the handler dependency in the controller, and at the same time have access to the listener in the handler model.

@unitedworx: I haven't looked too much into facades jus yet, but what you say sound mighty promising. (Edit: Ahh you edited your answer while I wrote this! Thank you! I'll def look into facades now.)

Thank you all for great answers!

Please or to participate in this conversation.