Laravel如何将JSON属性转换为Enum枚举类型?
解决Laravel中JSON列属性转Enum的问题
直接在$casts里同时使用AsArrayObject::class和settings->user_level的Enum转换是不可行的——因为当你用AsArrayObject接管整个JSON列的转换时,Laravel不会再单独处理该列内的子属性转换逻辑。
推荐通过自定义Cast类来实现需求,具体步骤如下:
1. 创建自定义Cast类
在app/Casts目录下创建SettingsWithEnum.php,继承AsArrayObject并扩展转换逻辑:
<?php namespace App\Casts; use App\Enums\User\UserLevel as UserLevelEnum; use Illuminate\Database\Eloquent\Casts\AsArrayObject; class SettingsWithEnum extends AsArrayObject { // 从数据库读取时,将user_level转为Enum实例 public function get($model, $key, $value, $attributes) { $arrayObject = parent::get($model, $key, $value, $attributes); if (isset($arrayObject['user_level'])) { $arrayObject['user_level'] = UserLevelEnum::from($arrayObject['user_level']); } return $arrayObject; } // 写入数据库时,将Enum实例转为对应值 public function set($model, $key, $value, $attributes) { if (isset($value['user_level']) && $value['user_level'] instanceof UserLevelEnum) { $value['user_level'] = $value['user_level']->value; } return parent::set($model, $key, $value, $attributes); } }
2. 修改User模型的$casts配置
替换原来的AsArrayObject::class为自定义的Cast类:
<?php namespace App\Models; use App\Casts\SettingsWithEnum; use App\Enums\User\UserLevel as UserLevelEnum; use Illuminate\Database\Eloquent\Model; class User extends Model { protected $casts = [ 'settings' => SettingsWithEnum::class, ]; }
这样处理后,当你访问$user->settings['user_level']时,会直接得到UserLevelEnum的实例;保存模型时,Enum会自动转换为对应的值存入JSON列。
内容的提问来源于stack exchange,提问作者S_R
相关产品推荐
相关产品推荐

