class ExampleUserService
{
public function approve($user, $data)
{
$approvedUser = DB::transaction(function () use ($user, $data) {
if ($data['approve_by_admin'] == 1) {
$this->updateAdminStatus($user);
}
$user->update(['approved' => 1]); // This fires updated event
});
}
public function updateAdminStatus($user, $data)
{
$user = DB::transaction(function () use ($user, $data) {
//Some Logic
$user->update(['status' => 5]); // This doesn't fire event
});
}
}
I have Scenario like above where same model gets updated in nested transactions but observer get only changes of last transaction, i want to get all updates in observer for same model.
class ExampleUserService
{
public function approve($user, $data)
{
$approvedUser = DB::transaction(function () use ($user, $data) {
if ($data['approve_by_admin'] == 1) {
$this->updateAdminStatus($user);
}
$user->update(['approved' => 1]); // This fires updated event
});
}
public function updateAdminStatus($user, $data)
{
$user = DB::transaction(function () use ($user, $data) {
//Some Logic
$user->update(['status' => 5]); // This doesn't fire event
});
}
}
I have Scenario like above where same model gets updated in nested transactions but observer get only changes of last transaction, i want to get all updates in observer for same model.
Share Improve this question edited Mar 15 at 11:58 hakre 198k55 gold badges450 silver badges856 bronze badges Recognized by PHP Collective asked Mar 13 at 7:43 Dilip ThakreDilip Thakre 111 silver badge1 bronze badge1 Answer
Reset to default 1Laravel waits until all transactions are finished before it triggers any observer events. This means if you update a model several times within nested transactions, only the last update’s change will trigger the observer.
To fix this -> Separate the transactions so that each update commits independently
public function approve(User $user, array $data)
{
if ($data['approve_by_admin'] == 1) {
$this->updateAdminStatus($user);
}
DB::transaction(function () use ($user) {
$user->update(['approved' => 1]);
});
}
And there are few issues/typos:
Class name should be
ServiceA
notService A
Wrap the whole data in a single array
$user->update(['approved' => 1]); # not $user->update(['approved'] => 1); $user->update(['status' => 5]); # not $user->update(['status'] => 5);
in
updateAdminStatus($user){
your're passing one param$this->updateAdminStatus($user);
, why this has twouse ($user, $data) {
public function updateAdminStatus(User $user) { DB::transaction(function () use ($user) { $user->update(['status' => 5]); }); }
FYI: Model Observer is kinda different what you have tried here. In short its like event-listener. Official doc