You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 02:27:52