First of all, apologies for the title of this one - I spent more time trying to figure out what to put there, than I did writing all this out
I have 2 models. Course and Booking. A Course hasMany Bookings, and a Booking belongsTo a Course.
class Course extends Model
{
public $hasMany = ['bookings', Booking::class];
}
class Booking extends Model
{
public $belongsTo= ['course', Course::class];
}
A booking has a qty, and a status attribute that can be âAwaiting, Confirmed or Cancelledâ
The course model has an attributes available_spaces and open_spaces. It has a method called getRemainingSpaces
that is used to set the open spaces value. This method calls another method, getBookingsQty
. This method loops through the related Bookings using the reduce collection method to calculate the total qty for bookings that donât have a cancelled status.
// Course.php
public function getRemainingSpaces()
{
return $this->available_spaces - $this->getBookingsQty();
}
public function getBookingsQty()
{
$qty = $this->bookings->reduce(function ($total, $booking) {
if ($booking->status == 'cancelled') {
return $total;
}
return $total + $booking->qty;
});
return $qty ?? 0;
}
When a bookingâs status is changed to cancelled, I want to update the open_spaces
value on the Course model. So Iâve put some logic inside the Bookingâs afterSave method to do this.
// Booking.php
public function afterSave()
{
$course = $this->course;
/*
* This is still including the recently updated booking's qty even
* though it's status has been changed to cancelled
*/
$course->open_spaces = $course->getRemainingSpaces();
$course->save();
}
The problem Iâm having is that the Booking that Iâve just saved isnât being reflected in itâs related Courseâs related bookings in the afterSave()
method.
Is this a bug, or is there a way around it?