Jamie
Jamie

Reputation: 10906

Laravel observer not triggered

I register an observer in the boot method of AppServiceProvider.

Then I listen with Queue::after when a certain job has been finished.

The problem is that when I create the ProjectUserAssignments in the foreach loop the observer is not triggered! But they are correctly made within the database.

It looks like this:

ProjectUserAssignment::observe(ProjectUserAssignmentObserver::class);

Queue::after(function(JobProcessed $event) {
    //When a project is created, create the employees and send to harvest.
    if($event->job->resolveName() == HarvestProjectCreate::class) {
        \Log::debug('start!');
        $project = Project::latest()->first();

        foreach($project->team->employees as $employee) {
            ProjectUserAssignment::create([
                'project_id' => $project->id,
                'user_id'    => $employee->id,
                'is_project_manager' => false
            ]);
        }
    }
}); 

When I individually make 1 ProjectUserAssignment the observer is triggered! What could be going on here?

Upvotes: 1

Views: 5752

Answers (2)

Apit John Ismail
Apit John Ismail

Reputation: 2155

Its mention in the Laravel Document that mass assignment method like create will not trigger events like observer.

You have to change to normal insert like

$p = new ProjectUserAssignment;
$p->project_id = $project->id;
$p->user_id = $employee->id;
$p->is_project_manager = false;
$p->save();
unset($p) // do this when done in loop to avoid memory shortage

Upvotes: 3

Peter Pointer
Peter Pointer

Reputation: 4170

I have had problems with an observer triggering on created as well and still not too firm with Laravel.
I cannot provide a true answer what the problem is, but hints on where to debug.

Add dd() or Log::info() calls to see if methods from your app are actually triggered.
This is not limited to your code base. Sometimes you need to look at the internals.

HasEvents

Location: Illuminate\Database\Eloquent\Concerns\HasEvents

  • HasEvents::observe() - The $classes parameter should have yours listed as well.
  • HasEvents::registerObserver() - Debug the foreach to see if some event doesn't actually exist.
  • HasEvents::fireModelEvent() - This is called from the base Model of Laravel when a model event happens (such as created, updated, etc.). Your observer should be called from here if everything is correct.
  • HasEvents::withoutEvents() - Be aware that automatic tests may run without model events. Illuminate\Foundation\Testing\TestCase does so if trait WithoutEvents is used.

Model

Location: Illuminate\Database\Eloquent\Model

  • Model::performInsert() - Inserting into the database ('creating', 'created')
  • Model::performUpdate() - Updating record in the database ('updating', 'updated')
  • Model::delete() - Deleting record from the database ('deleting', 'deleted')
  • fireModelEvent() calls - Other events are fired here as well, Ctrl+F your way through if you are interested

Typo?

If all else fails, check the spelling of files, classes and methods, namespace.

Especially relevant if you have hand-written some classes/methods or copy&pasted code for another Laravel version. Have to mention this, just-in-case.

This is sadly more often than not at the root of the problem. Everything else might be worth a ticket for the Laravel dev team. Provided you have an example project to test this on.

Upvotes: 1

Related Questions