GraphQL Ruby:如何编写具有多个参数的 DRY 突变?

gue*_*gui 3 ruby ruby-on-rails graphql

我正在使用 app为我的graphql-ruby编写一个基于devise- jwt的身份验证系统。在这个过程中,我为创建一个新的用户帐户做了一个改变,它需要 7 个参数,这在我的代码中产生了很多重复:

module Mutations
  class SignUpMutation < Mutations::BaseMutation
    argument :email, String, required: true
    argument :password, String, required: true
    argument :family_name, String, required: true
    argument :family_name_phonetic, String, required: true
    argument :given_name, String, required: true
    argument :given_name_phonetic, String, required: true
    argument :newsletter_optin, Boolean, required: false

    field :token, String, null: true
    field :user, Types::UserType, null: true

    def resolve(email:, password:,
                family_name:, family_name_phonetic:,
                given_name:, given_name_phonetic:,
                newsletter_optin:
               )
      result = {
        token: nil,
        user: nil
      }
      new_user = User.new(
        email: email,
        password: password,
        family_name: family_name,
        family_name_phonetic: family_name_phonetic,
        given_name: given_name,
        given_name_phonetic: given_name_phonetic,
        newsletter_optin: newsletter_optin
      )
      if new_user.save!
        result[:token] = new_user.token
        result[:user] = new_user
      end
      result
    end
  end
end

Run Code Online (Sandbox Code Playgroud)

我怎么能干掉这个以避免在所有地方重复突变参数的名称?

先感谢您!

gue*_*gui 5

回答我自己的问题。不必处理这么多参数的正确方法是使用输入对象而不是单独的参数。来自graphql-ruby 文档

输入对象类型是 GraphQL 操作的复杂输入。它们非常适合需要大量结构化输入的字段,例如突变或搜索字段。

所以我已经定义了我的输入对象:

module Types
  class UserAttributes < Types::BaseInputObject
    description 'Attributes for creating or updating a user'
    argument :email, String, required: true
    argument :password, String, required: true
    argument :family_name, String, required: true
    argument :family_name_phonetic, String, required: true
    argument :given_name, String, required: true
    argument :given_name_phonetic, String, required: true
    argument :newsletter_optin, Boolean, required: false
  end
end
Run Code Online (Sandbox Code Playgroud)

然后像这样重构我的突变:

module Mutations
  class SignUpMutation < Mutations::BaseMutation
    argument :attributes, Types::UserAttributes, required: true

    field :token, String, null: true
    field :user, Types::UserType, null: true

    def resolve(attributes:)
      result = {
        token: nil,
        user: nil
      }
      new_user = User.new(attributes.to_hash)
      if new_user.save!
        result[:token] = new_user.token
        result[:user] = new_user
      end
      result
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

最后,这段代码感觉更像 ruby​​ :)