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

GraphQL与Laravel Lighthouse:基于关联字段传递变量的类型问题

问题描述

我正在为本地体育俱乐部开发一款应用,需按运动类别(数据库中为category)提供标准问题(每类5个)并收集答案,之后对答案进行审核批准/驳回。数据库包含questions、answers、assessment三张表,结构如下:

questions
 - category_id
 - question_id
 - question

answers
- user_id
- question_id

assessment
 - user_id
 - category_id
 - approved
  ....

我希望通过传入user_id的GraphQL调用获取该用户提交的所有答案,已定义如下GraphQL类型:

type Assessment {
    id: ID!
    user_id: User! @belongsTo
    category: Category! @belongsTo
    selfAssessmentQuestions: CategoryAssessmentQuestions! @hasMany
    selfAssessmentAnswers: CategoryAssessmentAnswers! @hasMany
    submitted_at: DateTime
    reviewed_at: DateTime
    approved: Int!
    assessor_note: String
    created_at: DateTime
    updated_at: DateTime
}


type CategoryAssessmentQuestions{
    active: Int
    question_id: Int
    question: String
}

type CategoryAssessmentAnswers{
    id: ID!
    user_id: User! @belongsTo
    question (question_id: Int @eq): [CategoryAssessmentQuestions] @hasOne
    answer: String
    created_at: DateTime
    updated_at: DateTime
}

目前我可以获取用户X的所有assessment记录,但需要将查询得到的category_id传递给selfAssessmentQuestions节点,以获取对应类别的问题。若使用普通Eloquent查询会让GraphQL失去意义。

核心问题:能否在同一GraphQL类型中,基于其他查询结果进行数据查询?

解决方案

当然可以在同一GraphQL类型中基于其他字段的结果查询数据,核心是利用自定义字段解析器或关联注解动态传入当前模型参数,以下是三种可行实现方式:

方法1:使用注解绑定当前模型字段(以Laravel Lighthouse为例)

在Assessment类型的selfAssessmentQuestions字段上添加@where注解,直接引用当前assessment的category_id作为查询条件:

type Assessment {
    # ... 其他字段
    selfAssessmentQuestions: [CategoryAssessmentQuestions!]! @hasMany @where(column: "category_id", value: "$category_id")
    # ... 其他字段
}

$category_id会自动关联当前Assessment实例的category_id属性,查询每个Assessment时,会自动拉取对应类别的问题。

方法2:自定义字段解析器

如果注解方式不够灵活,可编写自定义解析函数实现逻辑:

  1. 修改GraphQL类型定义,去掉自动关联注解:
type Assessment {
    # ... 其他字段
    selfAssessmentQuestions: [CategoryAssessmentQuestions!]!
    # ... 其他字段
}
  1. 编写解析器类(Laravel环境示例):
namespace App\GraphQL\Resolvers;

use App\Models\Assessment;
use App\Models\Question;
use Illuminate\Database\Eloquent\Collection;

class AssessmentResolver
{
    public function selfAssessmentQuestions(Assessment $assessment): Collection
    {
        return Question::where('category_id', $assessment->category_id)->get();
    }
}
  1. 在GraphQL schema中绑定解析器:
extend type Assessment {
    selfAssessmentQuestions: [CategoryAssessmentQuestions!]! @field(resolver: "App\\GraphQL\\Resolvers\\AssessmentResolver@selfAssessmentQuestions")
}

方法3:预先定义Eloquent关联

在Assessment模型中定义关联关系,让GraphQL自动复用:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Assessment extends Model
{
    // ... 其他模型代码

    public function selfAssessmentQuestions(): HasMany
    {
        return $this->hasMany(Question::class, 'category_id', 'category_id');
    }
}

之后在GraphQL类型中保留@hasMany注解即可:

type Assessment {
    # ... 其他字段
    selfAssessmentQuestions: [CategoryAssessmentQuestions!]! @hasMany
    # ... 其他字段
}

以上三种方法均符合GraphQL设计理念,无需脱离GraphQL上下文编写独立Eloquent查询。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 15:27:49