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

如何在Lighthouse GraphQL的Mutation中实现排除自身的唯一验证

解决方案:在Input内实现排除自身的唯一验证

方法1:利用Laravel内置unique规则+动态参数

修改你的VoteCategoryInput定义,给name字段的@rules指令添加排除当前ID的条件,通过Lighthouse的参数占位符获取更新的ID:

input VoteCategoryInput {
    name: String! @rules(apply: [
        "required",
        "unique:vote_categories,name,{{$args.id}}"
    ])
    # 其他字段(如描述、状态等)
}

对应的updateVoteCategory Mutation定义需要明确接收id参数:

type Mutation {
    updateVoteCategory(id: ID!, input: VoteCategoryInput!): VoteCategory @update
}

这里{{$args.id}}会自动引用Mutation的id参数,Laravel的unique规则会自动排除该ID对应的记录,避免更新时检测到自身重复。

方法2:自定义验证规则类(更灵活)

如果需要更复杂的逻辑,比如多字段联合唯一,或者需要额外判断,可以自定义Laravel验证规则类:

  1. 创建规则类app/Rules/UniqueVoteCategoryName.php:
<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;
use Illuminate\Support\Facades\Request;

class UniqueVoteCategoryName implements Rule
{
    protected $ignoreId;

    public function __construct()
    {
        // 从GraphQL请求参数中获取要更新的ID
        $graphqlArgs = Request::get('variables');
        $this->ignoreId = $graphqlArgs['id'] ?? null;
    }

    public function passes($attribute, $value)
    {
        $query = \App\Models\VoteCategory::where('name', $value);
        
        // 如果是更新操作,排除当前ID的记录
        if ($this->ignoreId) {
            $query->where('id', '!=', $this->ignoreId);
        }
        
        return !$query->exists();
    }

    public function message()
    {
        return '投票分类名称已存在,请更换其他名称';
    }
}
  1. 在VoteCategoryInput中引用该规则:
input VoteCategoryInput {
    name: String! @rule(apply: ["required", "App\\Rules\\UniqueVoteCategoryName"])
    # 其他字段
}

解决自定义验证器的类型转换/必填问题

如果之前用@validator指令关联到Mutation时出现必填错误,可能是因为验证器没有正确处理Input的结构。正确的验证器写法应该直接从验证数据中获取Input字段:

<?php

namespace App\Validators;

use Nuwave\Lighthouse\Validation\Validator;

class VoteCategoryInputValidator extends Validator
{
    public function rules(): array
    {
        $id = $this->args['id'];
        
        return [
            'input.name' => [
                'required',
                \Illuminate\Validation\Rule::unique('vote_categories')->ignore($id)
            ]
        ];
    }

    public function messages(): array
    {
        return [
            'input.name.unique' => '投票分类名称已存在'
        ];
    }
}

然后在Mutation中关联:

type Mutation {
    updateVoteCategory(id: ID!, input: VoteCategoryInput!): VoteCategory 
        @update
        @validator(class: "App\\Validators\\VoteCategoryInputValidator")
}

这种方式下,验证器直接复用Laravel的Rule::unique()->ignore()逻辑,自动处理排除自身的需求,同时避免类型转换问题。

内容的提问来源于stack exchange,提问作者mstdmstd

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 23:33:10