使用nuwave/lighthouse的@json指令时遇Undefined index: id错误
问题分析
错误Undefined index: id出现在自定义JsonDirective中,原因是使用@updateOrCreate创建新用户时,模型尚未完成持久化(无id值),但JsonDirective的逻辑中假设模型已存在(依赖id字段),导致索引未找到的报错。
解决方案
方案一:使用Lighthouse原生输入类型处理JSON字段(推荐)
无需自定义@json指令,通过定义嵌套输入类型直接传递JSON结构,让Laravel Eloquent自动处理JSON字段赋值:
1. 更新Users.graphql定义
extend type Mutation { updateOrCreateLanguageSpecificUsers( user_id: Int @rules(apply: ["numeric"]) language_mapping: LanguageMappingInput ): Users @updateOrCreate(search: ["user_id"]) } input LanguageMappingInput { hobbies: HobbiesInput } input HobbiesInput { en: String de: String da: String }
2. 调整GraphQL mutation请求
mutation { updateOrCreateLanguageSpecificUsers( user_id: 4171, language_mapping: { hobbies: { en: "singing" } } ){ language_mapping { hobbies { en } } } }
方案二:修改自定义JsonDirective适配创建场景
如果必须保留原有的字符串格式(如hobbies.en=singing),需要修改JsonDirective.php代码,处理模型未保存的情况:
<?php namespace App\GraphQL\Directives; use Nuwave\Lighthouse\Schema\Directives\BaseDirective; use Nuwave\Lighthouse\Support\Contracts\FieldMiddleware; use Illuminate\Support\Arr; use GraphQL\Type\Definition\ResolveInfo; use Nuwave\Lighthouse\Exceptions\ValidationException; class JsonDirective extends BaseDirective implements FieldMiddleware { public function handle($rootValue, array $args, \Closure $next, ResolveInfo $resolveInfo) { $model = $rootValue; $jsonColumn = $this->directiveArgValue('columns')[0]; $input = $args[$jsonColumn] ?? ''; if (empty($input)) { return $next($rootValue, $args); } // 解析输入格式:path=value list($path, $value) = explode('=', $input, 2); if (!$path || !$value) { throw ValidationException::withMessages([ $jsonColumn => 'Invalid format. Use "path=value" (e.g. hobbies.en=singing)' ]); } // 获取当前JSON字段的值,不存在则初始化空数组 $currentData = $model->{$jsonColumn} ?? []; // 嵌套赋值 Arr::set($currentData, $path, $value); // 赋值回模型 $model->{$jsonColumn} = $currentData; // 移除对id字段的依赖,直接处理模型属性 return $next($rootValue, $args); } }
关键修改点
- 移除对模型
id字段的依赖,直接基于模型的language_mapping属性处理,无论模型是否已保存 - 增加输入格式的异常校验,避免非法输入导致报错
内容的提问来源于stack exchange,提问作者vivek.p.n manu
相关产品推荐
相关产品推荐

