You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 9新属性修改器赋值报错,Laravel 8旧写法正常,原因何在?

问题

Laravel 9+ 提供了新的属性修改器(mutator)格式,我按文档定义了如下访问器与修改器:

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);
        }
    );
}

同时在模型中设置了:

protected $appends = ['full_name'];

但执行以下赋值保存操作时:

$model->full_name = 'John Doe';
$model->save();

出现错误:

Column not found: 1054 Unknown column 'full_name' in 'field list

而使用 Laravel 8 的旧写法定义修改器则无报错:

public function setFullNameAttribute(?string $value): void
{
    $names = explode(' ', $value);

    $this->attributes['first_name'] = array_shift($names);
    $this->attributes['last_name'] = implode(' ', $names);
}

为何新修改器格式无法正常赋值?

原因与解决方法

问题出在新的 Attribute 系统的默认行为上:

  • 旧写法的修改器通过魔术方法(setXXXAttribute)处理,Laravel 不会将 full_name 视为数据库实际列,只会触发对应的拆分逻辑。
  • 新的 Attribute 定义方式默认会将属性标记为「可填充」,当你把 full_name 加入 $appends 后,Laravel 执行 save() 时会错误地将这个虚拟属性当作数据库字段写入,因此抛出「列不存在」的错误。

解决方法很简单,只需在 Attribute 实例上调用 ->fillable(false),明确标记该属性不需要被填充到数据库:

use Illuminate\Database\Eloquent\Casts\Attribute;

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);
        }
    )->fillable(false); // 关键:禁止该属性被当作数据库列处理
}

修改后,赋值 $model->full_name = 'John Doe' 时只会触发 set 方法的拆分逻辑,将值存入 first_name 和 last_name 字段,不会再尝试写入 full_name 虚拟属性。

内容的提问来源于stack exchange,提问作者eComEvo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 20:50:33