Laravel 9+ has this new mutator format according to the docs:
public function fullName(): Attribute
{
return Attribute::make(
get: fn() => trim($this->first_name.' '.$this->last_name),
set: function (?string $value) {
$names = explode(' ', $value);
$this->attributes['first_name'] = array_shift($names);
$this->attributes['last_name'] = implode(' ', $names);
}
);
}
In my model I have this:
protected $appends = ['full_name'];
However, if I try to save the value like this:
$model->full_name = 'John Doe';
$model->save();
Then I get the error:
Column not found: 1054 Unknown column 'full_name' in 'field list
However, if I use the old way to format mutator setter methods like this then there is no error:
public function setFullNameAttribute(?string $value): void
{
$names = explode(' ', $value);
$this->attributes['first_name'] = array_shift($names);
$this->attributes['last_name'] = implode(' ', $names);
}
Why doesn't the new mutator format work when setting values?
Setting the attributes property was the problem. The values should be returned as an array in the setter for Laravel to handle itself.
protected function fullName(): Attribute
{
return Attribute::make(
get: fn(mixed $value, array $attr) => trim($attr['first_name'].' '.$attr['last_name']),
set: function (?string $value) {
$names = explode(' ', $value);
return [
'first_name' => array_shift($names),
'last_name' => implode(' ', $names),
];
}
);
}