Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
graphql / lib / graphql / schema / mutation.rb
Size: Mime:
# frozen_string_literal: true

module GraphQL
  class Schema
    # This base class accepts configuration for a mutation root field,
    # then it can be hooked up to your mutation root object type.
    #
    # If you want to customize how this class generates types, in your base class,
    # override the various `generate_*` methods.
    #
    # @see {GraphQL::Schema::RelayClassicMutation} for an extension of this class with some conventions built-in.
    #
    # @example Creating a comment
    #  # Define the mutation:
    #  class Mutations::CreateComment < GraphQL::Schema::Mutation
    #    argument :body, String, required: true
    #    argument :post_id, ID, required: true
    #
    #    field :comment, Types::Comment, null: true
    #    field :error_messages, [String], null: false
    #
    #    def resolve(body:, post_id:)
    #      post = Post.find(post_id)
    #      comment = post.comments.build(body: body, author: context[:current_user])
    #      if comment.save
    #        # Successful creation, return the created object with no errors
    #        {
    #          comment: comment,
    #          errors: [],
    #        }
    #      else
    #        # Failed save, return the errors to the client
    #        {
    #          comment: nil,
    #          errors: comment.errors.full_messages
    #        }
    #      end
    #    end
    #  end
    #
    #  # Hook it up to your mutation:
    #  class Types::Mutation < GraphQL::Schema::Object
    #    field :create_comment, mutation: Mutations::CreateComment
    #  end
    #
    #  # Call it from GraphQL:
    #  result = MySchema.execute <<-GRAPHQL
    #  mutation {
    #    createComment(postId: "1", body: "Nice Post!") {
    #      errors
    #      comment {
    #        body
    #        author {
    #          login
    #        }
    #      }
    #    }
    #  }
    #  GRAPHQL
    #
    class Mutation < GraphQL::Schema::Resolver
      extend GraphQL::Schema::Member::HasFields

      class << self
        # Override this method to handle legacy-style usages of `MyMutation.field`
        def field(*args, &block)
          if args.none?
            raise ArgumentError, "#{name}.field is used for adding fields to this mutation. Use `mutation: #{name}` to attach this mutation instead."
          else
            super
          end
        end

        # Call this method to get the derived return type of the mutation,
        # or use it as a configuration method to assign a return type
        # instead of generating one.
        # @param new_payload_type [Class, nil] If a type definition class is provided, it will be used as the return type of the mutation field
        # @return [Class] The object type which this mutation returns.
        def payload_type(new_payload_type = nil)
          if new_payload_type
            @payload_type = new_payload_type
          end
          @payload_type ||= generate_payload_type
        end

        alias :type :payload_type
        alias :type_expr :payload_type

        # An object class to use for deriving payload types
        # @param new_class [Class, nil] Defaults to {GraphQL::Schema::Object}
        # @return [Class]
        def object_class(new_class = nil)
          if new_class
            @object_class = new_class
          end
          @object_class || (superclass.respond_to?(:object_class) ? superclass.object_class : GraphQL::Schema::Object)
        end

        def field_class(new_class = nil)
          if new_class
            @field_class = new_class
          else
            @field_class || find_inherited_method(:field_class, GraphQL::Schema::Field)
          end
        end

        # An object class to use for deriving return types
        # @param new_class [Class, nil] Defaults to {GraphQL::Schema::Object}
        # @return [Class]
        def object_class(new_class = nil)
          if new_class
            @object_class = new_class
          end
          @object_class || (superclass.respond_to?(:object_class) ? superclass.object_class : GraphQL::Schema::Object)
        end

        private

        # Build a subclass of {.object_class} based on `self`.
        # This value will be cached as `{.payload_type}`.
        # Override this hook to customize return type generation.
        def generate_payload_type
          mutation_name = graphql_name
          mutation_fields = fields
          mutation_class = self
          Class.new(object_class) do
            graphql_name("#{mutation_name}Payload")
            description("Autogenerated return type of #{mutation_name}")
            mutation(mutation_class)
            mutation_fields.each do |name, f|
              field(name, field: f)
            end
          end
        end
      end
    end
  end
end