Skip model accessor

I got a model called Run which contains this method:

public function getNameAttribute($name){
    if($name == 'Eendaags')
        return $this->race_edition->race->name;

    return $this->race_edition->race->name.' '.$name;
}

I need this setup for laravel administrator, since alot of runs will have the same name and the only difference is the race name. But in 1 place in the website i need to get the name only, without mutating. Is this possbile?


Solution 1:

this is the correct way

// that skips mutators
$model->getOriginal('name');

https://laravel.com/api/5.2/Illuminate/Database/Eloquent/Model.html#method_getOriginal

Edit: Careful!

As Maksym Cierzniak explained in the comments, getOriginal() doesn't just skip mutators, it also returns the "original" value of the field at the time the object was read from the database. So if you have since modified the model's property, this won't return your modified value, it will still return the original value. The more consistent and reliable way to get the un-mutated value from within the model class is to retrieve it from the attributes property like this:

$this->attributes['name']

But be aware that attributes is a protected property, so you can't do that from outside the model class. In that case, you can use

$model->getAttributes()['name']`

or Maksym's technique from his comment below.

Solution 2:

since Laravel 7.x and 8.x there is a new approach to access intact attribute:

// that skips accessors
$model->getRawOriginal('name');

https://laracasts.com/discuss/channels/testing/how-to-disable-casting-during-testing

Solution 3:

I was running into an issue with Eloquent accessors and form model binding - by formatting an integer with money_format, the value was no longer being loaded into the form number input field.

The workaround I am using is to create an accessor with a different name:

public function getRevenueDollarsAttribute($value)
{
    return money_format('$%i', $this->revenue);
}

This provides me with an accessor without affecting the form model binding.

Solution 4:

In my case for Laravel 7.15.0

public function getOriginalNameAttribute()
{
    return $this->attributes['name'];
}

// access it via
$user->originalName;