Laravel中枚举转换列关联预加载报错,如何兼顾两者?
问题描述
我创建了RoleEnum枚举,并在User模型中对role_id字段进行枚举转换,该字段同时与Role模型存在关联关系。
枚举代码
<?php namespace App\Enums; enum RoleEnum:int { case SYSTEM_ADMINISTRATOR = 1; case ADMINISTRATOR = 2; case SAMPLE_ROLE_ONE = 3; case SAMPLE_ROLE_TWO = 4; case SAMPLE_ROLE_THREE = 5; case SAMPLE_ROLE_FOUR = 6; }
User模型代码
protected $casts = [ 'email_verified_at' => 'datetime', 'password' => 'hashed', 'role_id' => RoleEnum::class, ]; public function role(): BelongsTo { return $this->belongsTo(Role::class); }
控制器代码
$users = User::with('role') ->paginate() ->withQueryString();
执行时出现错误:
Object of class App\Enums\RoleEnum could not be converted to string
经测试,错误由枚举转换字段的关联预加载导致,移除枚举转换即可正常运行。请问如何在保留枚举转换的同时使用关联预加载?
解决方案
错误核心原因:Laravel预加载关联时,会从User模型实例中读取role_id属性作为外键查询Role模型,但此时role_id已被转换为RoleEnum对象,无法直接转为字符串/整数用于SQL查询。以下两种方法可解决:
方法一:给枚举添加__toString()方法
修改RoleEnum类,添加__toString()方法,让枚举对象在需要转字符串时自动返回对应整数值:
<?php namespace App\Enums; enum RoleEnum:int { case SYSTEM_ADMINISTRATOR = 1; case ADMINISTRATOR = 2; case SAMPLE_ROLE_ONE = 3; case SAMPLE_ROLE_TWO = 4; case SAMPLE_ROLE_THREE = 5; case SAMPLE_ROLE_FOUR = 6; public function __toString(): string { return (string)$this->value; } }
这样Laravel收集外键值时,会自动将枚举对象转为对应整数字符串,正常执行关联查询。
方法二:用访问器替代字段转换
若不想修改枚举类,可将枚举转换逻辑放到访问器中,保留role_id原始整数类型用于关联:
- 移除
casts中的role_id枚举转换:
protected $casts = [ 'email_verified_at' => 'datetime', 'password' => 'hashed', ];
- 添加访问器和追加属性:
protected $appends = ['role_enum']; public function getRoleEnumAttribute(): RoleEnum { return RoleEnum::from($this->role_id); }
之后可通过$user->role_enum获取枚举对象,同时role_id仍为整数,关联预加载不受影响。
内容的提问来源于stack exchange,提问作者Kenneth
相关产品推荐
相关产品推荐

