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

valentin_vranic's avatar

Laravel 10 #[ObservedBy()] attribute doesn't trigger

I'm trying to use ObservedBy, to register an observer to a class, but without success. php: v8.2.0 laravel: v10.47.0

#[ObservedBy([UserObserver::class])]
class User extends Model

I'm calling the update like this (using Livewire Form extraction), within transaction:

DB::beginTransaction();
try {
    $this->user->update(
        $this->user->getDirty()
    );

} catch (Exception $e) {
    // logging error
    DB::rollBack();
}
DB::commit();

The observer:

class UserObserver implements ShouldHandleEventsAfterCommit

The update is successful in database, but does not trigger the updated event in UserObserver.

EDIT: When I register it in EventServiceProvider, it works as it supposed to. Weird

protected $observers = [
    User::class => [UserObserver::class],
];
0 likes
12 replies
LaryAI's avatar
Level 58

It seems like you're trying to use the #[ObservedBy()] attribute to register an observer in Laravel 10. However, you're facing an issue where the observer's events are not being triggered. Here's a solution that might help you resolve this issue:

First, ensure that your UserObserver class is properly defined with the necessary event methods. For example, if you want to observe the updated event, your observer should have an updated method:

class UserObserver
{
    public function updated(User $user)
    {
        // Handle the "updated" event.
    }
}

Next, make sure that the UserObserver class is imported correctly at the top of your User model file:

use App\Observers\UserObserver;

Now, let's look at your User model. The #[ObservedBy()] attribute should be used correctly as you have done:

use Illuminate\Database\Eloquent\Model;
use App\Observers\UserObserver;

#[ObservedBy([UserObserver::class])]
class User extends Model
{
    // Model content
}

Regarding the transaction block in your Livewire component, it's important to note that the ShouldHandleEventsAfterCommit interface is used to defer the event handling until after the database transaction has been committed. This means that if you're using database transactions, the events will only be dispatched after the DB::commit() call.

Here's the correct way to use transactions with the observer:

use Exception;
use Illuminate\Support\Facades\DB;

// ...

DB::beginTransaction();

try {
    $this->user->update(
        $this->user->getDirty()
    );
    DB::commit(); // Commit before catching exceptions
} catch (Exception $e) {
    DB::rollBack();
    // Log the error
    throw $e; // Rethrow the exception or handle it as needed
}

Make sure to commit the transaction before catching exceptions. If an exception is thrown, the DB::rollBack() call will revert the transaction, and the observer events will not be dispatched.

If you've followed all these steps and the observer is still not being triggered, you might want to clear your application cache to ensure that the framework is aware of the new observer. You can do this by running the following Artisan command:

php artisan optimize:clear

Lastly, ensure that your observer is not registered elsewhere in your application, such as in a service provider, as this could potentially cause conflicts with the #[ObservedBy()] attribute.

If you've checked all these points and the issue persists, it might be a bug with the framework or a more specific issue with your application setup. In that case, consider reporting the issue to the Laravel GitHub repository or seeking further assistance from the community.

Snapey's avatar

I don't understand this code

$this->user->update(
        $this->user->getDirty()
    );

Why dont you just call $user->save() ?

Why do you need a transaction wrapping a single update? This has no effect.

valentin_vranic's avatar

@Snapey thanks for advices.

I'm using extracted Livewire form, that's why I'm calling it like that. The transaction is more like testing.

But even if I change it to $this->user->save(); and rename the updated to saved in the observer, it won't run into. I've removed the transaction, and implements ShouldHandleEventsAfterCommit too

cemilakan's avatar

also i have the same problem with #[ScopedBy([ForexScope::class])]

Mervus's avatar

I am currently having the same problem in laravel 10.47

valentin_vranic's avatar

Well, I've returned back to my own question, because I've realized, that my local environment wasn't in synchron with my live test server. And the laravel versions were different. So on the real test server, I've updated from 10.42 to 10.48.12 and it works perfectly!

getupkid203's avatar

I am having the same problem too. Laravel 11. PHP 8.3.1.

No idea how to get it to work.

valentin_vranic's avatar

@getupkid203 Were you using save() or update()? Because later on (again getting back to my own question), I found out that only the save() method calls the updating and updated events. And ONLY when data are changed!

getupkid203's avatar

@valentin_vranic I worked out that I hadn't imported the ObservedBy class (rookie mistake haha)...

use Illuminate\Database\Eloquent\Model;
use App\Observers\UserObserver;
use Illuminate\Database\Eloquent\Attributes\ObservedBy; // Gotta import this

#[ObservedBy([UserObserver::class])]
class User extends Model
{
    // Model content
}

Please or to participate in this conversation.