Module: GraphQL::Define::InstanceDefinable

Included in:
Argument, BaseType, GraphQL::Directive, Field, Relay::Mutation, Schema
Defined in:
lib/graphql/define/instance_definable.rb

Overview

This module provides the ‘.define { … }` API for BaseType, Field and others.

Calling ‘.accepts_definitions(…)` creates:

  • a keyword to the ‘.define` method

  • a helper method in the ‘.define { … }` block

The ‘.define { … }` block will be called lazily. To be sure it has been called, use the private method `#ensure_defined`. That will call the definition block if it hasn’t been called already.

The goals are:

  • Minimal overhead in consuming classes

  • Independence between consuming classes

  • Extendable by third-party libraries without monkey-patching or other nastiness

Examples:

Make a class definable

class Car
  attr_accessor :make, :model
  accepts_definitions(
    # These attrs will be defined with plain setters, `{attr}=`
    :make, :model,
    # This attr has a custom definition which applies the config to the target
    doors: ->(car, doors_count) { doors_count.times { car.doors << Door.new } }
  )

  def initialize
    @doors = []
  end
end

# Create an instance with `.define`:
subaru_baja = Car.define do
  make "Subaru"
  model "Baja"
  doors 4
end

# The custom proc was applied:
subaru_baja.doors #=> [<Door>, <Door>, <Door>, <Door>]

Extending the definition of a class

# Add some definitions:
Car.accepts_definitions(all_wheel_drive: GraphQL::Define.(:all_wheel_drive))

# Use it in a definition
subaru_baja = Car.define do
  # ...
  all_wheel_drive true
end

# Access it from metadata
subaru_baja.[:all_wheel_drive] # => true

Defined Under Namespace

Modules: ClassMethods Classes: AssignAttribute, AssignMetadataKey

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



60
61
62
# File 'lib/graphql/define/instance_definable.rb', line 60

def self.included(base)
  base.extend(ClassMethods)
end

Instance Method Details

#define(**kwargs, &block) ⇒ void

This method returns an undefined value.

Mutate this instance using functions from its definitions. Keywords or helpers in the block correspond to keys given to ‘accepts_definitions`.

Note that the block is not called right away – instead, it’s deferred until one of the defined fields is needed.



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/graphql/define/instance_definable.rb', line 84

def define(**kwargs, &block)
  # make sure the previous definition_proc was executed:
  ensure_defined

  @definition_proc = ->(obj) {
    kwargs.each do |keyword, value|
      public_send(keyword, value)
    end

    if block
      instance_eval(&block)
    end
  }
  nil
end

#definition_proc=(defn_block) ⇒ Object

Set the definition block for this instance. It can be run later with #ensure_defined



66
67
68
# File 'lib/graphql/define/instance_definable.rb', line 66

def definition_proc=(defn_block)
  @definition_proc = defn_block
end

#metadataHash<Object, Object>

‘metadata` can store arbitrary key-values with an object.

Returns:

  • (Hash<Object, Object>)

    Hash for user-defined storage



73
74
75
76
# File 'lib/graphql/define/instance_definable.rb', line 73

def 
  ensure_defined
  @metadata ||= {}
end