Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect changes when saving Laravel 4: Eloquent

I'm using the Laravel 4 framework and I am trying to work out a way to display notifications depending on whether a save() was successful or not. Here's what I have so far:

    if($user->save()) {
        Session::flash('success','woohoo success');
    } else {
        Session::flash('error','uhoh error');
    }
    return Redirect::action('UsersController@show', array('users' => $id));

My problem is that it always returns true when a user is saved, even if no changes have been made to the database (I know this from the updated_at timestamp). Is there a way to detect whether any changes have actually been made or not using Laravel?

like image 563
Karl Avatar asked Nov 24 '13 19:11

Karl


2 Answers

Depending on what you want to achieve, you have some options here. Check out the below first.

Model Hooks with Ardent package
If you are interested in autovalidating models, take a look at the https://github.com/laravelbook/ardent package - Self-validating smart models for Laravel Framework 4's Eloquent O/RM. Apart form great validation features it offers additional model hooks you can use:

Here's the complete list of available hooks:

before/afterCreate()
before/afterSave()
before/afterUpdate()
before/afterDelete()
before/afterValidate() - when returning false will halt validation, thus making save() operations fail as well since the validation was a failure.

Laravel Model Events
If you dont want to use any additional stuff, you can just use the Laravel Model Events (that in fact Ardent is wrapping in the hooks). Look into the docs http://laravel.com/docs/eloquent#model-events

Eloquent models fire several events, allowing you to hook into various points in the model's lifecycle using the following methods: creating, created, updating, updated, saving, saved, deleting, deleted, restoring, restored.

Whenever a new item is saved for the first time, the creating and created events will fire. If an item is not new and the save method is called, the updating / updated events will fire. In both cases, the saving / saved events will fire.

If false is returned from the creating, updating, saving, or deleting events, the action will be cancelled:

Solution
Finally, reffering to you question you can utilize the above approaches in numerous ways but most obviously you can combine it (or not) with the Eloquent Models' getDirty() api docs here method. It will work for example with the saving event.

Yourmodel::saving(function($model)
{
    foreach($model->getDirty() as $attribute => $value){
        $original= $model->getOriginal($attribute);
        echo "Changed $attribute from '$original' to '$value'<br/>\r\n";
    }
    return true; //if false the model wont save! 
});
like image 197
Gadoma Avatar answered Sep 29 '22 16:09

Gadoma


You can take a look at the getDirty() method in the Eloquent model (model.php). This method should return the changed attributes.

like image 21
Rob Gordijn Avatar answered Sep 29 '22 15:09

Rob Gordijn