なかなか情報がなかったので、書いときます。
model名が◯◯Typeで終わることって、ままあるのかなと思います。CompanyモデルとCompanyTypeモデルのような感じで。これをGraphQLでTypeを定義しようとすると、Types::CompanyTypeとTypes::CompanyTypeTypeになってしまいます。読みにくすぎる…。
後ろにTypeがつかないといかんのか?っていうところも疑問だったのですが、別にそんなルールもないみたいでした。
GraphQL - Scalars をみていたら、class Types::Url < Types::BaseScalarとやっていたので。
また、デフォルトのディレクトリ構造のままだとtypesディレクトリに大量のファイルが作られて見辛くなってきたので、ディレクトリを分けました。
ここを参考に、ほぼ同様の構成にしました。
app/graphql/enum_types/
/input_types/
/interface_types/
/mutations/
/object_types/
/scalar_types/
/types/
/union_types/
ディレクトリ名を名前空間として、ファイル名をクラス名にした構成にしないといけないため、ファイルの移動後はリネーム祭りに。
Types::FooTypeはObjectTypes::Fooのように修正です。
これで、Types::CompanyTypeがObjectTypes::Companyへ、Types::CompanyTypeTypeがObjectTypes::CompanyTypeへと分かりやすく変更できてよかった!と思っていたのですが、これだけだと動きません。
query {
company(id: 1) {
id
name
companyType {
id
name
}
}
}
上記のようなクエリを発行しようとすると、エラーで落ちました。
{
"error": {
"message": "Duplicate type definition found for name 'Company' at 'Field Company.companyType's return type' (ObjectTypes::Company, ObjectTypes::CompanyType)",
"backtrace": [
# 略
Companyで定義されているcompanyTypeに当てはまるTypeが重複してるぞ!って言われてます。
module ObjectTypes class Company < Types::BaseObject field :id, ID, null: false field :name, String, null: false field :company_type, ObjectTypes::CompanyType, null: false # ここ end end
いやいや、ObjectTypes::CompanyTypeって指定してるじゃん!って思うんですが、メタプログラミングしてるんでしょう。多分、別名をつけるメソッドとかあるだろう…と思ってググるとDSL形式の頃のgraphql-rubyのコードだったけれど、name = 'CompanyType'みたいなことをしているページを発見。
Shinosaka.rb #27 (GraphQL) に参加した - @znz blog
CompanyTypeのほうに、雑にname 'CompanyType'を追加してみます。
module ObjectTypes class CompanyType < Types::BaseObject name 'CompanyType' # 雑に追加 field :id, ID, null: false field :name, String, null: false end end
その後、適当にクエリを投げてみると、エラーメッセージが変わりました。
{
"error": {
"message": "The new name override method is `graphql_name`, not `name`. Usage: graphql_name \"CompanyType\"",
"backtrace": [
# 略
graphql_nameメソッドで別名を定義しろと。
module ObjectTypes class CompanyType < Types::BaseObject graphql_name 'CompanyType' # 修正 field :id, ID, null: false field :name, String, null: false end end
すると、エラーが消え、ちゃんとcompany(id: 1)に紐づくCompanyTypeの情報が取得できました😀
追記:rails cで検証
検証のために、該当箇所をコメントアウトしてみます。
module ObjectTypes class CompanyType < Types::BaseObject # graphql_name 'CompanyType' # コメントアウト field :id, ID, null: false field :name, String, null: false end end
rails cして確認します。
$ bin/rails c Loading development environment (Rails 5.2.2.1) Frame number: 0/16 [1] pry(main)> ObjectTypes::CompanyType.graphql_name => "Company" [2] pry(main)> ObjectTypes::Company.graphql_name => "Company"
CompanyTypeのgrqphql_nameはCompanyとなってしまい、重複してますね。その後、コメントアウトを解除して再度rails cしてみます。
$ bin/rails c Loading development environment (Rails 5.2.2.1) Frame number: 0/16 [1] pry(main)> ObjectTypes::CompanyType.graphql_name => "CompanyType" [2] pry(main)> ObjectTypes::Company.graphql_name => "Company"
重複しなくなったのでOK!