Hi,
I'm trying to add a model observer for a CRUD model:
namespace App\Observers;
use App\Admin;
class AdminObserver
{
/**
* Listen to the Admin created event.
*
* @param Admin $admin
* @return void
*/
public function created(Admin $admin)
{
dd('created');
}
public function updated(Admin $admin)
{
dd('updated');
}
}
Created works fine and triggers when I add a new admin.
However the 'updated' listener never seems to get triggered when updating an entry. Nor does 'saved'.
I've noticed the Laravel docs say:
When issuing a mass update via Eloquent, the saved and updated model events will not be fired for the updated models. This is because the models are never actually retrieved when issuing a mass update.
Is this why the 'updated' listener doesn't get called? Is there any way around this?
Many thanks.
@tabacitu any ideas? I've just had a go myself and can confirm its not firing, unless we're both doing something wrong? Might need to manually trigger it if not?
@OwenMelbz @Eminee
Backpack update looks like mass update to me https://github.com/Laravel-Backpack/CRUD/blob/master/src/PanelTraits/Update.php
I guess you can overwrite the update method like this in your controller:
public function update(UpdateRequest $request)
{
// triger updated event in this method
$result = parent::updateCrud($request);
// triger
}
or if you want to go further:
this is the updateCrud Method. Overwrite it and have fun:
public function updateCrud(UpdateRequest $request = null)
{
$this->crud->hasAccessOrFail('update');
// fallback to global request instance
if (is_null($request)) {
$request = \Request::instance();
}
// replace empty values with NULL, so that it will work with MySQL strict mode on
foreach ($request->input() as $key => $value) {
if (empty($value) && $value !== '0') {
$request->request->set($key, null);
}
}
// update the row in the db
$this->crud->update($request->get($this->crud->model->getKeyName()),
$request->except('redirect_after_save', '_token'));
// show a success message
\Alert::success(trans('backpack::crud.update_success'))->flash();
return \Redirect::to($this->crud->route);
}
Hi guys,
@indra1 , actually the code you sent proves it is NOT a bulk operation :-) We do findOrFail() first. So events should work fine, I've used them in a few projects.
@Eminee , as far as I know the updating and updated events are only fired if an edit was made. If you submit the edit form without actually modifying anything, Eloquent will notice that and it will not execute an "UPDATE" sql command, so it will no longer trigger the event either. Please also test by editing something in the form. Does it fix it for you?
But it's very odd that saved doesn't work for you. I just tried all events again:
saving, creating, created, saved;saving, updating, updated, saved when I modified a field;saving, saved when I didn't modify anything;deleting, deleted;Soo... seems to be working fine.
Are you sure you didn't have a typo when you tried saved? Can you try again and share the observer if it doesn't work?
Cheers!
Thanks for your reply @tabacitu, you are completely right - it was because we weren't editing any data. I'm not sure why saved didn't work though, must have been my mistake.
Thanks for your help!
Glad to help.
Cheers!
I'm really sorry to remark on such an old issue @tabacitu but I honestly cannot understand how to properly set a field when updating a record.
Eg: On a Phrase model, combine/adjust text_a and text_b and save in text_full column.
I've tried the following:
Following the 4.1 docs precisely. $this->crud->request->request->add(['text_full' => ...]) results in Cannot access protected property Backpack\CRUD\app\Library\CrudPanel\CrudPanel::$request
Following a suggestion from the docs and here to use Eloquent events, the update event never seems to fire no matter what. (I've added a dd to the the updated method of a PhraseObserver and added this to the AppServiceProvider.
Following a suggestion from #51 results in Method App\Http\Controllers\Admin\PhraseCrudController::storeCrud does not exist.
I'm not sure how relevant these issues are as they refer to much older versions of Backpack, but a solution for problem 1 or a clearer documentation for how to implement the event observer would be really helpful, I'm so
Ok, finally, after a tip from a user in the gitter that you're not able to access the $request from CrudPanel class anymore and to inherit the variable $request = request(); which addresses points 1 and 3 from above.
Then, with all old examples pointing to parent::updateCrud which doesn't work, I finally found the solution in the 4.0 upgrade notes
It's particularly confusing that the documentation also changes between 4.0 and 4.1 thus feeling up to date/correct: $this->crud->request->request->add(['author_id'=> backpack_user()->id]); which, from what I can understand, is incorrect?
Can the documentation please be updated to reflect the correct way to do this?
This also sadly doesn't explain why the Eloquent events weren't being fired.
Ugh. Sorry for the frustration this must have cause you @alancwoo - indeed, this is something that might not be clearly documented, I'll take some time to re-evaluate how we explain this, and update the docs. Thanks a lot!
Most helpful comment
Hi guys,
@indra1 , actually the code you sent proves it is NOT a bulk operation :-) We do
findOrFail()first. So events should work fine, I've used them in a few projects.@Eminee , as far as I know the
updatingandupdatedevents are only fired if an edit was made. If you submit the edit form without actually modifying anything, Eloquent will notice that and it will not execute an "UPDATE" sql command, so it will no longer trigger the event either. Please also test by editing something in the form. Does it fix it for you?But it's very odd that
saveddoesn't work for you. I just tried all events again:saving,creating,created,saved;saving,updating,updated,savedwhen I modified a field;saving,savedwhen I didn't modify anything;deleting,deleted;Soo... seems to be working fine.
Are you sure you didn't have a typo when you tried
saved? Can you try again and share the observer if it doesn't work?Cheers!