Ruby GraphQL报错:发现UpdateTransactionInput存在两个可见定义
问题
使用graphql gem开发时,创建更新记录的Mutation遇到重复定义错误,报错信息:
Found two visible definitions for UpdateTransactionInput: #Class:0x0000000106dae998, Inputs::UpdateTransactionInput
相关代码如下:
MutationType定义
module Types class MutationType < Types::BaseObject field :createTransaction, mutation: Mutations::CreateTransaction field :updateTransaction, mutation: Mutations::UpdateTransaction end end
UpdateTransaction Mutation实现
# app/graphql/mutations/update_transaction.rb module Mutations class UpdateTransaction < Mutations::BaseMutation graphql_name "UpdateTransaction" argument :id, ID, required: true argument :input, Inputs::UpdateTransactionInput, required: true def resolve(input:) transaction = Transaction.find(input[:id]) (...) end end end
UpdateTransactionInput输入类
module Inputs class UpdateTransactionInput < Types::BaseInputObject graphql_name "UpdateTransactionInput" description "Attributes for updating a transaction" puts "Loading Inputs::UpdateTransactionInput" # Debug line argument :id, ID, required: true argument :due_date, String, required: true argument :description, String, required: true argument :amount, Float, required: true end end
使用的查询语句:
mutation UpdateTransaction($input:UpdateTransactionInput!) { updateTransaction(input: $input) { id dueDate description amount __typename } __typename }
已确认仅定义过一次该输入类,重命名后错误依然存在。
解决方案
这个错误核心原因是GraphQL类型系统中重复注册了同名输入类,可按以下步骤排查解决:
检查输入类文件的唯一性与加载路径
- 确认
app/graphql/inputs/update_transaction_input.rb是唯一的输入类文件,没有其他目录下的副本。Rails自动加载机制对文件名大小写敏感,避免出现UpdateTransactionInput.rb和update_transaction_input.rb共存的情况。 - 检查
config/application.rb中的自动加载配置,确保app/graphql目录只被添加一次:config.autoload_paths << Rails.root.join('app/graphql') config.eager_load_paths << Rails.root.join('app/graphql')
- 确认
移除Mutation中冗余的
id参数
当前Mutation同时定义了独立的:id参数和包含:id的input参数,可能干扰类型解析逻辑。建议将:id统一放在input内部,Mutation仅接收input参数:# 修改后的UpdateTransaction Mutation module Mutations class UpdateTransaction < Mutations::BaseMutation graphql_name "UpdateTransaction" argument :input, Inputs::UpdateTransactionInput, required: true def resolve(input:) transaction = Transaction.find(input[:id]) # ... 后续更新逻辑 end end end清除类型缓存
- 重启Rails服务器,彻底清理内存中加载的旧类型。
- 若使用Spring预加载工具,执行
spring stop后再重启服务器,避免缓存残留。
排查自动生成的类型冲突
检查项目是否使用了GraphQL自动生成工具(如graphql-ruby的生成器),这类工具可能自动创建同名输入类,与手动定义的类型冲突。查看生成命令历史或相关配置,关闭不必要的自动生成规则。验证类加载次数
观察调试代码puts "Loading Inputs::UpdateTransactionInput"的输出次数,如果打印多次,说明类被重复加载。可通过调整加载顺序或禁用部分自动加载路径解决。
内容的提问来源于stack exchange,提问作者cleicar
相关产品推荐
相关产品推荐

