Reputation: 10906
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
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
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.
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.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 interestedIf 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