Laravel 9/InertiaJS/Vue配置Accessor转换StatusID为字符串
问题描述
我是Laravel/Inertia/Vue新手,有PHP和JS基础。之前试过用枚举处理,现在想通过模型Accessor把数据库中不可修改的整数字段StatusID转换成字符串,让Eloquent获取后传给Inertia时是字符串类型。目前Accessor未生效,Vue里仍显示StatusID的整数值,怀疑是驼峰命名被自动转换为status_id导致的问题,求排查和解决方法。
Controller代码
<?php namespace App\Http\Controllers; use Inertia\Inertia; use Illuminate\Http\Request; use App\Models\eRequester\Requisition; use App\Models\eRequester\ProjectManager; class RequisitionController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { return Inertia::render('Requisition/Index',[ 'requisitions' => Requisition::with( 'lines:RequisitionLineID,ItemID,Description,ProjectNumber,RequisitionID', 'owner:UserID,UserName,FirstName,LastName') ->latest() ->where('StatusID','!=','2') ->limit(15) ->select('RequisitionID','Title','UserID','StatusID') // << 需要转换的StatusID字段 ->get(), 'projectmanagers' => ProjectManager::where('AttributeID','siica3') ->orWhere('AttributeID','ckwca7') ->orWhere('AttributeID','orica3') ->get(), 'companies' => [ ['CompanyID' => '3', 'CompanyName' => 'Spitzer'], ['CompanyID' => '2', 'CompanyName' => 'Curtis Kelly'], ['CompanyID' => '4', 'CompanyName' => 'Orizon']], ]); } }
Model代码
// 注意:需要导入Attribute类 // use Illuminate\Database\Eloquent\Casts\Attribute; protected function StatusID(): Attribute { $statusDescription = [ "0" => "Incomplete", "1" => "Unsubmitted", "2" => "Cancelled", "3" => "Rejected", "4" => "Waiting", "5" => "Request Info", "6" => "Approved", "7" => "Posted", "8" => "Partially Received", "9" => "Closed", "10" => "Require Change", "11" => "Resubmitted for Post Approval Routing", "12" => "Edited (Post Approval)", "13" => "Fully Received", "14" => "Posted - On Hold" ]; return Attribute::make( get: fn ($value) => $statusDescription[$value], ); }
Vue代码
<div class="p-4 border-2 mb-4 rounded-lg"> <div class="text-white font-bold uppercase flex justify-between"> <span class=""> <a target="_BLANK" :href="'{redacted}/req/review.aspx?reqid=' + req.RequisitionID"> <button class="bg-white hover:bg-blue-200 text-black font-bold py-0 px-2 mr-2 mb-2 rounded transition-all"> {{ req.RequisitionID }} </button></a> {{ req.Title }} </span> <span> {{ req.StatusID }} </span> </div>
排查与解决方法
1. 检查Attribute类导入
首先确保模型文件顶部导入了Attribute类,否则Accessor无法正常工作:
use Illuminate\Database\Eloquent\Casts\Attribute;
2. 处理Laravel的字段命名转换问题
Laravel Eloquent默认会将数据库中的驼峰字段(如StatusID)自动转换为蛇形命名的模型属性(status_id),这是导致你的Accessor不生效的核心原因。有两种解决方案:
方案一:适配蛇形属性命名
- 修改模型Accessor方法名:将
StatusID()改为statusId()(对应蛇形属性status_id的驼峰写法):
protected function statusId(): Attribute { $statusDescription = [ // 状态映射保持不变 "0" => "Incomplete", "1" => "Unsubmitted", // ... 其他状态 ]; return Attribute::make( get: fn ($value) => $statusDescription[$value], ); }
- 修改Vue模板中的属性名:将
{{ req.StatusID }}改为{{ req.status_id }}:
<span> {{ req.status_id }} </span>
方案二:关闭自动蛇形属性转换
如果你想保留原驼峰字段名(StatusID),可以在Requisition模型中添加$snakeAttributes = false;,禁用Laravel的自动命名转换:
class Requisition extends Model { public $snakeAttributes = false; // 添加这一行 // ... 其他模型代码 protected function StatusID(): Attribute { // Accessor逻辑保持不变 } }
这种情况下,模型属性会直接使用数据库字段名StatusID,你的原有Accessor和Vue代码无需修改即可生效。
3. 验证Accessor是否生效
可以在Controller中临时添加调试代码,确认Accessor是否正常工作:
$requisition = Requisition::first(); dd($requisition->StatusID); // 或 $requisition->status_id,根据方案不同调整
如果输出的是状态字符串而非整数,说明Accessor已经生效,剩下的就是确保Vue端使用正确的属性名。
内容的提问来源于stack exchange,提问作者alexhowl
相关产品推荐
相关产品推荐

