Capripot
Capripot

Reputation: 1509

How to share arguments between two Mutation classes

In my Rails API project using graphql-ruby, I have two Mutations that stands for two slightly different flows. They share a lot of arguments and I would like to keep it DRY, avoiding repeating the similar arguments, so when we change them, we don't accidentally forget to change the other.

I was wondering how I could solve this problem without falling into the boolean/flag trap resulting in a tangled implementation.

I could use concepts of inheritance or composition, but how to do it ?

module Mutations
  class CreateThing < BaseMutation
    argument :argument1, Float, required: true
    argument :argument2, Float, required: true
    argument :argument3, Float, required: true
    argument :specific_arg, String, required: false

    def resolve(**kwargs)
      new_thing = kwargs.merge(
        assignee:                 current_user
      )

      Things::Create.call(company: current_company, new_thing: new_thing)
    end
  end
end
module Mutations
  class CreateFlexibleThing < BaseMutation
    argument :argument1, Float, required: true
    argument :argument2, Float, required: true
    argument :argument3, Float, required: true
    argument :other_arg, String, required: false
    argument :link, String, required: true

    def resolve(**kwargs)
      new_thing = kwargs.merge(
        assignee:                 current_user
      )

      Things::Create.call(company: current_company, new_thing: new_thing)
    end
  end
end

Upvotes: 1

Views: 438

Answers (1)

Capripot
Capripot

Reputation: 1509

A good way I found is using mixins.

With the help of SuperModule or ActiveSupport::Concern, I think it yields a pretty clean code.

app/graphql/mutations/create_thing.rb

module Mutations
  class CreateThing < BaseMutation

    include Mixins::CreateThingArguments 

    argument :specific_arg, String, required: false

    def resolve(**kwargs)
      new_thing = kwargs.merge(
        assignee:                 current_user
      )

      Things::Create.call(company: current_company, new_thing: new_thing)
    end
  end
end

app/graphql/mutations/create_flexible_thing.rb

module Mutations
  class CreateFlexibleThing < BaseMutation

    include Mixins::CreateThingArguments 

    argument :other_arg, String, required: false
    argument :link, String, required: true

    def resolve(**kwargs)
      new_thing = kwargs.merge(
        assignee:                 current_user
      )

      Things::Create.call(company: current_company, new_thing: new_thing)
    end
  end
end

app/graphql/mutations/mixins/create_thing_arguments.rb

module Mutations::Mixins
  class CreateThingArguments
    extend ActiveSupport::Concern
    include GraphQL::Types # Make sure to include types

    included do
      argument :argument1, Float, required: true
      argument :argument2, Float, required: true
      argument :argument3, Float, required: true
    end
  end
end

Upvotes: 1

Related Questions