Framework: Eloquent not triggering mutators

Created on 27 Feb 2016  路  9Comments  路  Source: laravel/framework

Whenever I do $model->update() it won't trigger the mutators, but when you do $model->create() it does.

Is this a legit bug or is it meant to not trigger?

Most helpful comment

I'd like to submit that this is a bug.

I have a model that has an accessor (adding puts a number through number_format() to add comma(s) where needed). If I try to update an unrelated attribute the update will fail.

Easy example:

class MovieTheater extends BaseModel {
    protected $rules = [
        'ticket_qty' => 'integer',
    ];

    public function getTicketQty($value) {
        return number_format($this->attributes['ticket_qty']);
    }

    public function setTicketQtyAttribute($value) {
        $this->attributes['ticket_qty'] = preg_replace('/[^0-9]?/', '', $value);
    }

    public function changePrice($new_price) {
        return $this->update(['ticket_price' => $new_price]);
    }
} 

The changePrice method will not work. In fact, update() will not work on the model in any instance once you've set an accessor and a rule. If this is expected behavior then it would seem the expectation is that using accessors breaks update() at the model level.

It seems logical that if the accessor is triggered on $this then the mutator should as well on update.

All 9 comments

Can you show the complete code of how you call the update() method?

I have a notice here:

If the checkbox is not checked $request->all() won't contain the double_rewards key, this will make the Model::setAttribute() method never called on that key and thus the mutator won't fire.

To fix that I suggest you do something like:

    public function update( VoteSiteRequest $request, VoteSite $vote )
    {
        $input = $request->all();

        $input['double_rewards'] = isset($input['double_rewards']) ? $input['double_rewards'] : 0;

        $vote->update( $input );

        flash()->success( trans( 'vote.edit_success' ) );

        return redirect( 'admin/vote' );
    }

That way a double_rewards key will always be present when updating the model.

@themsaid, It won't fire if its checked either.

Here you have {!! Form::checkbox( 'double_rewards', NULL, NULL) the value if checked = null.

 public function setDoubleRewardsAttribute( $value )
    {
        $this->attributes['double_rewards'] = $value ? 1 : 0;
    }

$this->attributes['double_rewards'] here will always be Zero since $value will be NULL if the checkbox is checked.

I confirm there's no issue with mutators, at least for 5.2.21 as I'm using it in a project.

Your incorrect... if I were to make a new model via the form it would set the value to 1 in the database if the value was on. It's ONLY not triggering when i do $model->update().

Then I'm unable to help. Sorry :)

@huludini Model events and mutators are triggered only with $model->save(). Why do you use update instead?
Update is for generating SQL UPDATE operations and it doesn't consider eloquent features.
So I think it's expected behaviour.

I'd like to submit that this is a bug.

I have a model that has an accessor (adding puts a number through number_format() to add comma(s) where needed). If I try to update an unrelated attribute the update will fail.

Easy example:

class MovieTheater extends BaseModel {
    protected $rules = [
        'ticket_qty' => 'integer',
    ];

    public function getTicketQty($value) {
        return number_format($this->attributes['ticket_qty']);
    }

    public function setTicketQtyAttribute($value) {
        $this->attributes['ticket_qty'] = preg_replace('/[^0-9]?/', '', $value);
    }

    public function changePrice($new_price) {
        return $this->update(['ticket_price' => $new_price]);
    }
} 

The changePrice method will not work. In fact, update() will not work on the model in any instance once you've set an accessor and a rule. If this is expected behavior then it would seem the expectation is that using accessors breaks update() at the model level.

It seems logical that if the accessor is triggered on $this then the mutator should as well on update.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Anahkiasen picture Anahkiasen  路  3Comments

RomainSauvaire picture RomainSauvaire  路  3Comments

digirew picture digirew  路  3Comments

lzp819739483 picture lzp819739483  路  3Comments

Fuzzyma picture Fuzzyma  路  3Comments