Home > Software design >  Eloquent `update()` method also updates dirty columns
Eloquent `update()` method also updates dirty columns

Time:10-24

I noticed when i use eloquent update() method it also updates dirty column:

$user = User::find(1);

$user->is_admin = 1;

$user->update(['first_name' => 'Alex']);

//is_admin updated to 1   !

Shouldn't it only update first_name column?

What eloquent method only updates the given fields and ignores dirty columns ?

Note that I know about refresh and fresh methods which adds additional query which is not the method I look for.

CodePudding user response:

To reset the Model attributes to the original one (from the first query or last fresh/refresh) use syncOriginal()

It will not work when used after the update in this case because when you update using the model instance, it will also update the dirty attribute is_admin (check your database).

as the file definition shows, it still runs ->save() on the model and will save the change on the is_admin too.

/**
     * Update the model in the database.
     *
     * @param  array  $attributes
     * @param  array  $options
     * @return bool
     */
    public function update(array $attributes = [], array $options = [])
    {
        if (! $this->exists) {
            return false;
        }

        return $this->fill($attributes)->save($options);
    }

The solution would be to ignore the instance and go through a new query

$user = User::find(1);

$user->is_admin = 1;

User::whereKey($user->getKey())->update(['first_name' => 'Alex']);

//you should also set it in the model
$user->first_name = 'Alex';
$user->setOriginalAttribute('first_name', 'Alex');

CodePudding user response:

There's no built-in method to revert values before updating as far as I know but you can probably make your own:

$user = User::find(1);

$user->is_admin = 1;

$user->update(array_merge($user->getOriginal(), ['first_name' => 'Alex']));

This should only update first_name but might also revert the dirty attributes

  • Related