Framework: Model Observers, Updated/Updating not Firing

Created on 8 Jan 2016  路  16Comments  路  Source: laravel/framework

I've been facing this issue for the past 2 days, and had no luck finding any solution.
I did a generic observer for my models, which works fine for create and delete, but for some reason it does not work at all for update.

For more detailed info and code: http://laravel.io/forum/01-07-2016-model-observers-not-working-for-update

http://stackoverflow.com/questions/34663078/model-observer-not-working-for-update

Most helpful comment

@vitroz Your didn't provide correct parameters for the update method: https://github.com/laravel/framework/blob/5.2/src/Illuminate/Database/Eloquent/Model.php#L1475

And also, update events are only fired when you update your model directly without building a new query.

So, this will fire events:

$model = MyModel::find($id);
$model->update($data);

And this won't:

MyModel::where('id', $id)->update($data);

This is intentional, since updating models with a query could potentially update millions of rows at once and it's a huge performance issue to fire events for each updated row.

All 16 comments

What laravel version please?

I've tested with both 5.1 and 5.2

What laravel version please?

As in, like 5.1.28, or what?

5.1.28

@vitroz Can you paste the code where you update the model?

Sure @acasar
Its in my controller, i get the data from my form and then perform the update inside the controller.

    public function putEdit($id, StorePainelRequest $request){

    $painel = $this->painelRepository->find($id);     

    if (!$painel) {
        Flash::error('Painel n茫o existe.');
        return redirect('/gestor/painel/index');
    }

    $data = $request->only('pai_app_id', 'pai_titulo', 'pai_subtitulo', 'pai_classcss', 'pai_observacao'); 

    $painel = $this->painelRepository->update($data,$painel->pai_id, 'pai_id');

    if (!$painel) {
        Flash::error('Erro ao tentar salvar.');
        return redirect()->back()->withInput($request->all());
    }

    Flash::success('Painel atualizado com sucesso.');
        return redirect('/gestor/painel/index');
} 

How is that repository updating the model?

@lagbox The repository is simply an instance of my model, so it has access to all the Model class methods

obs: Sorry for the delayed response! and still no luck solving this.

@vitroz Your didn't provide correct parameters for the update method: https://github.com/laravel/framework/blob/5.2/src/Illuminate/Database/Eloquent/Model.php#L1475

And also, update events are only fired when you update your model directly without building a new query.

So, this will fire events:

$model = MyModel::find($id);
$model->update($data);

And this won't:

MyModel::where('id', $id)->update($data);

This is intentional, since updating models with a query could potentially update millions of rows at once and it's a huge performance issue to fire events for each updated row.

Thank you guys so much for the support and help!
@acasar One last thing, could you provide me the right way to perform the update in my case?

The only query method i'm using is the "update",so the events are not firing because i'm using the repository instance? It bugs me because the update actually happens in the database. (I'll only be able to test it tomorrow, that's the reason for this question, sorry and thanks!)

    $painel = $this->painelRepository->update($data,$painel->pai_id, 'pai_id');

Instead of:

 $painel = $this->painelRepository->update($data,$painel->pai_id, 'pai_id');

Try doing:

 $painel->update($data);

And also make sure you have $fillable fields set correctly. Otherwise use forceUpdate($data).

@acasar Passing by to confirm, this solved it for me, thanks!

@acasar Can you please explain why the following is true?

This works: User::find(1)->update(['earings' => 0]);

While this doesn't:

$user = User::find(1); 
$user->earings=0; 
$user->update(). 

In the second case, the event is not being fired. Can you explain why? What is the difference between the two statements? From what I see the only difference is that in the second statement we run the update() method without passing the data (since we have already modified it through the $user instance). Is this the reason the event is not being fired? And why?

The second case is wrong. You should call save() instead of update(). Please refer to the docs.

You are right. It will work with save(). But the question is why it doesn't work when update() has no parameters.

you can do it such this
php $bookTrip=BookingTrip::where('id',$bookTrip_id)->where('driver_id',$driver_id)->first(); $bookTrip->current_status='new_status'; $bookTrip->save();

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Fuzzyma picture Fuzzyma  路  3Comments

SachinAgarwal1337 picture SachinAgarwal1337  路  3Comments

klimentLambevski picture klimentLambevski  路  3Comments

CupOfTea696 picture CupOfTea696  路  3Comments

YannPl picture YannPl  路  3Comments