Laravel 8模型追加full_name属性查询时报找不到字段错误如何解决
问题原因
- Laravel的访问器(
getXXXAttribute定义的字段)是SQL查询完成后,模型实例加载阶段才生成的计算属性,不属于数据库原生字段,不能直接放到select()方法中作为查询字段,否则会触发数据库字段不存在的报错。 - 现有代码还存在两处模型逻辑错误:
$appends属性要求为数组格式,你写成了字符串- 要追加
full_name属性,访问器名必须是getFullNameAttribute,你误写为getFullNameIdAttribute,导致就算正常查询也不会自动生成full_name属性
解决方法
方案1:使用访问器实现(推荐,符合Laravel常规写法)
第一步:修正模型代码
// 修正$appends为数组,访问器名匹配属性名 protected $appends = ['full_name']; public function getFullNameAttribute() { return ucfirst($this->last_name) . ', ' . ucfirst($this->first_name). ' ' . ucfirst($this->other_name); } // 可选:如果不需要返回原始姓名字段,添加到隐藏属性 protected $hidden = ['last_name', 'first_name', 'other_name'];
第二步:修正控制器查询逻辑
查询时只需要选择拼接full_name需要的数据库原生字段即可,访问器会自动追加属性:
public function employeeParameters() { try { // 选择生成full_name需要的所有字段 + id $employees = Employee::select('id', 'last_name', 'first_name', 'other_name')->get(); return $this->success('Vehicle Detail.', [ 'employees' => $employees, ]); } catch(\Throwable $e) { Log::error($e); return $this->error($e->getMessage(), $e->getCode()); } }
方案2:SQL层面直接拼接生成(不需要定义访问器)
如果不想用访问器,也可以直接在查询时通过SQL函数拼接生成full_name,性能更高适合大量数据查询的场景:
public function employeeParameters() { try { $employees = Employee::select('id', \DB::raw("CONCAT(UCASE(LEFT(last_name, 1)), SUBSTRING(last_name, 2), ', ', UCASE(LEFT(first_name, 1)), SUBSTRING(first_name, 2), ' ', UCASE(LEFT(other_name, 1)), SUBSTRING(other_name, 2)) as full_name"))->get(); return $this->success('Vehicle Detail.', [ 'employees' => $employees, ]); } catch(\Throwable $e) { Log::error($e); return $this->error($e->getMessage(), $e->getCode()); } }
注:不同数据库的首字母大写函数可能有差异,以上是MySQL适配写法,如果用PostgreSQL可以直接用
initcap()函数简化。
内容的提问来源于stack exchange,提问作者user11352561
相关产品推荐
相关产品推荐

