Rails + graphql-rubyでapollo_upload_serverを使ってファイルアップロード→activeStorageへ登録を試してみていて
ApolloUploadServer::Upload型の入力データを
modelにattachしてみたらエラーがでました
入力データの定義
module Types
class UserInputObject < Types::BaseInputObject
argument :avatar, ApolloUploadServer::Upload, "user profile picture", required: false
end
end
エラー内容
Could not find or build blob: expected attachable, got #<ActionDispatch::Http::UploadedFile:0x000055d4a2a41240
これを解決するまでのメモです。
結論
こちらissueのコメントを参考に
ApolloUploadServer::Upload型を使うのをやめて、
自分でscalar型を宣言することで解決しました。
https://github.com/jetruby/apollo_upload_server-ruby/issues/10#issuecomment-394729475
こんな感じです。
module Types
class ImageFile < Types::BaseScalar
description "upload file type"
def self.coerce_input(file, context)
file
end
end
経緯
ActionDispatch::Http::UploadedFileではないのかと確認してみる
p input.avatar.class
結果→ApolloUploadServer::Wrappers::UploadedFile
調べてみるとActionDispatch::Http::UploadedFileのwrapperクラスであることがわかる
↓
mutationのresolverで
ApolloUploadServer::Wrappers::UploadedFileから
ActionDispatch::Http::UploadedFileのインスタンスを取得できないかと考える
↓
ソースを確認し、簡単には無理そうだなと理解
# frozen_string_literal: true
require 'delegate'
require 'action_dispatch/http/upload'
module ApolloUploadServer
module Wrappers
class UploadedFile < DelegateClass(::ActionDispatch::Http::UploadedFile)
def initialize(wrapped_foo)
super
end
def as_json(options = nil)
instance_values.except('tempfile').as_json(options)
end
end
end
end
↓
検索し、公式のissueでこの問題について議論しているページを発見
https://github.com/jetruby/apollo_upload_server-ruby/issues/10
↓
いくつか解決方法が掲載されているけど
返却するとき(coerce_result)にも独自にscalar型を定義してactive_storageから
public_urlを取得する処理があったので
受け取る際の処理(coerce_input)に処理を書くかと結論の方法を採用
もし他にいい方法があるよ!って場合はご教授いただけると
ありがたいです。
よろしくお願いします!