graphql_rails 1.2.3 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +18 -0
  3. data/.hound.yml +1 -1
  4. data/.rubocop.yml +4 -0
  5. data/.ruby-version +1 -1
  6. data/CHANGELOG.md +19 -0
  7. data/Gemfile +3 -3
  8. data/Gemfile.lock +27 -25
  9. data/docs/README.md +1 -1
  10. data/docs/components/model.md +107 -13
  11. data/docs/other_tools/schema_dump.md +8 -8
  12. data/lib/graphql_rails/attributes/attributable.rb +6 -14
  13. data/lib/graphql_rails/attributes/attribute.rb +10 -34
  14. data/lib/graphql_rails/attributes/attribute_configurable.rb +45 -0
  15. data/lib/graphql_rails/attributes/attribute_name_parser.rb +7 -7
  16. data/lib/graphql_rails/attributes/input_attribute.rb +20 -14
  17. data/lib/graphql_rails/attributes/input_type_parser.rb +5 -7
  18. data/lib/graphql_rails/attributes/type_parseable.rb +55 -19
  19. data/lib/graphql_rails/attributes/type_parser.rb +4 -9
  20. data/lib/graphql_rails/concerns/chainable_options.rb +49 -0
  21. data/lib/graphql_rails/controller/build_controller_action_resolver/controller_action_resolver.rb +3 -0
  22. data/lib/graphql_rails/decorator/relation_decorator.rb +2 -2
  23. data/lib/graphql_rails/input_configurable.rb +10 -8
  24. data/lib/graphql_rails/model/build_graphql_input_type.rb +4 -2
  25. data/lib/graphql_rails/model/configurable.rb +30 -8
  26. data/lib/graphql_rails/model/configuration.rb +26 -12
  27. data/lib/graphql_rails/model/find_or_build_graphql_type.rb +23 -21
  28. data/lib/graphql_rails/model/find_or_build_graphql_type_class.rb +2 -1
  29. data/lib/graphql_rails/model/input.rb +10 -26
  30. data/lib/graphql_rails/model.rb +1 -1
  31. data/lib/graphql_rails/query_runner.rb +9 -3
  32. data/lib/graphql_rails/router/route.rb +2 -2
  33. data/lib/graphql_rails/tasks/dump_graphql_schema.rb +18 -27
  34. data/lib/graphql_rails/tasks/dump_graphql_schemas.rb +57 -0
  35. data/lib/graphql_rails/tasks/schema.rake +8 -5
  36. data/lib/graphql_rails/types/argument_type.rb +12 -0
  37. data/lib/graphql_rails/types/field_type.rb +14 -0
  38. data/lib/graphql_rails/types/hidable_by_group.rb +32 -0
  39. data/lib/graphql_rails/types/object_type.rb +12 -0
  40. data/lib/graphql_rails/version.rb +1 -1
  41. metadata +15 -8
  42. data/.travis.yml +0 -5
@@ -4,22 +4,19 @@ module GraphqlRails
4
4
  module Attributes
5
5
  # contains info about single graphql input attribute
6
6
  class InputAttribute
7
+ require 'graphql_rails/model/build_enum_type'
7
8
  require_relative './input_type_parser'
8
9
  require_relative './attribute_name_parser'
9
10
  include Attributable
11
+ include AttributeConfigurable
10
12
 
11
- attr_reader :description
13
+ chainable_option :subtype
14
+ chainable_option :enum
12
15
 
13
- # rubocop:disable Metrics/ParameterLists
14
- def initialize(name, type: nil, description: nil, subtype: nil, required: nil, options: {})
16
+ def initialize(name, config:)
17
+ @config = config
15
18
  @initial_name = name
16
- @initial_type = type
17
- @description = description
18
- @options = options
19
- @subtype = subtype
20
- @required = required
21
19
  end
22
- # rubocop:enable Metrics/ParameterLists
23
20
 
24
21
  def input_argument_args
25
22
  type = raw_input_type || input_type_parser.input_type_arg
@@ -28,7 +25,7 @@ module GraphqlRails
28
25
  end
29
26
 
30
27
  def input_argument_options
31
- { required: required?, description: description, camelize: false }
28
+ { required: required?, description: description, camelize: false, groups: groups }
32
29
  end
33
30
 
34
31
  def paginated?
@@ -37,7 +34,7 @@ module GraphqlRails
37
34
 
38
35
  private
39
36
 
40
- attr_reader :initial_name, :initial_type, :options, :subtype
37
+ attr_reader :initial_name, :config
41
38
 
42
39
  def attribute_name_parser
43
40
  @attribute_name_parser ||= AttributeNameParser.new(
@@ -51,14 +48,23 @@ module GraphqlRails
51
48
 
52
49
  def input_type_parser
53
50
  @input_type_parser ||= begin
54
- initial_parseable_type = initial_type || attribute_name_parser.graphql_type
51
+ initial_parseable_type = type || enum_type || attribute_name_parser.graphql_type
55
52
  InputTypeParser.new(initial_parseable_type, subtype: subtype)
56
53
  end
57
54
  end
58
55
 
56
+ def enum_type
57
+ return if enum.blank?
58
+
59
+ ::GraphqlRails::Model::BuildEnumType.call(
60
+ "#{config.name}_#{initial_name}_enum",
61
+ allowed_values: enum
62
+ )
63
+ end
64
+
59
65
  def raw_input_type
60
- return initial_type if initial_type.is_a?(GraphQL::InputObjectType)
61
- return initial_type.graphql_input_type if initial_type.is_a?(Model::Input)
66
+ return type if type.is_a?(GraphQL::InputObjectType)
67
+ return type.graphql_input_type if type.is_a?(Model::Input)
62
68
  end
63
69
  end
64
70
  end
@@ -15,12 +15,6 @@ module GraphqlRails
15
15
  @subtype = subtype
16
16
  end
17
17
 
18
- def graphql_type
19
- return nil if unparsed_type.nil?
20
-
21
- partly_parsed_type || parsed_type
22
- end
23
-
24
18
  def input_type_arg
25
19
  if list?
26
20
  list_type_arg
@@ -34,7 +28,11 @@ module GraphqlRails
34
28
  attr_reader :unparsed_type, :subtype
35
29
 
36
30
  def unwrapped_type
37
- raw_unwrapped_type || unwrapped_scalar_type || unwrapped_model_input_type || raise_not_supported_type_error
31
+ raw_unwrapped_type ||
32
+ unwrapped_scalar_type ||
33
+ unwrapped_model_input_type ||
34
+ graphql_type_object ||
35
+ raise_not_supported_type_error
38
36
  end
39
37
 
40
38
  def raw_unwrapped_type
@@ -16,18 +16,27 @@ module GraphqlRails
16
16
  'int' => GraphQL::Types::Int,
17
17
  'integer' => GraphQL::Types::Int,
18
18
 
19
+ 'big_int' => GraphQL::Types::BigInt,
20
+ 'bigint' => GraphQL::Types::BigInt,
21
+
22
+ 'float' => GraphQL::Types::Float,
23
+ 'double' => GraphQL::Types::Float,
24
+ 'decimal' => GraphQL::Types::Float,
25
+
26
+ 'bool' => GraphQL::Types::Boolean,
27
+ 'boolean' => GraphQL::Types::Boolean,
28
+
19
29
  'string' => GraphQL::Types::String,
20
30
  'str' => GraphQL::Types::String,
21
31
  'text' => GraphQL::Types::String,
22
- 'time' => GraphQL::Types::String,
23
- 'date' => GraphQL::Types::String,
24
32
 
25
- 'bool' => GraphQL::Types::Boolean,
26
- 'boolean' => GraphQL::Types::Boolean,
33
+ 'date' => GraphQL::Types::ISO8601Date,
27
34
 
28
- 'float' => GraphQL::Types::Float,
29
- 'double' => GraphQL::Types::Float,
30
- 'decimal' => GraphQL::Types::Float
35
+ 'time' => GraphQL::Types::ISO8601DateTime,
36
+ 'datetime' => GraphQL::Types::ISO8601DateTime,
37
+ 'date_time' => GraphQL::Types::ISO8601DateTime,
38
+
39
+ 'json' => GraphQL::Types::JSON
31
40
  }.freeze
32
41
 
33
42
  WRAPPER_TYPES = [
@@ -43,10 +52,16 @@ module GraphqlRails
43
52
  GraphQL::InputObjectType
44
53
  ].freeze
45
54
 
55
+ PARSEABLE_RAW_GRAPHQL_TYPES = [
56
+ GraphQL::Schema::Object,
57
+ GraphQL::Schema::Scalar,
58
+ GraphQL::Schema::Enum
59
+ ].freeze
60
+
46
61
  RAW_GRAPHQL_TYPES = (WRAPPER_TYPES + GRAPHQL_BASE_TYPES).freeze
47
62
 
48
63
  def unwrapped_scalar_type
49
- TYPE_MAPPING[nullable_inner_name.downcase.downcase]
64
+ TYPE_MAPPING[nullable_inner_name.downcase]
50
65
  end
51
66
 
52
67
  def raw_graphql_type?
@@ -58,25 +73,46 @@ module GraphqlRails
58
73
  end
59
74
 
60
75
  def core_scalar_type?
61
- unwrapped_scalar_type.in?(TYPE_MAPPING.values)
76
+ unwrapped_scalar_type.present?
62
77
  end
63
78
 
64
79
  def graphql_model
65
- type_class = \
66
- if unparsed_type.is_a?(Class) && unparsed_type < GraphqlRails::Model
67
- unparsed_type
68
- else
69
- nullable_inner_name.safe_constantize
70
- end
71
-
72
- return if type_class.nil?
73
- return unless type_class < GraphqlRails::Model
80
+ extract_type_class_if { |type| graphql_model?(type) }
81
+ end
74
82
 
75
- type_class
83
+ def graphql_type_object
84
+ type_object = extract_type_class_if { |type| graphql_type_object?(type) }
85
+ type_object || graphql_model&.graphql&.graphql_type
76
86
  end
77
87
 
78
88
  protected
79
89
 
90
+ def extract_type_class_if
91
+ return unparsed_type if yield(unparsed_type)
92
+
93
+ type_class = nullable_inner_name.safe_constantize
94
+ return type_class if yield(type_class)
95
+
96
+ nil
97
+ end
98
+
99
+ def graphql_model?(type_class)
100
+ type_class.is_a?(Class) && type_class < GraphqlRails::Model
101
+ end
102
+
103
+ def graphql_type_object?(type_class)
104
+ return false unless type_class.is_a?(Class)
105
+
106
+ PARSEABLE_RAW_GRAPHQL_TYPES.any? { |parent_type| type_class < parent_type }
107
+ end
108
+
109
+ def applicable_graphql_type?(type)
110
+ return false unless type.is_a?(Class)
111
+ return true if type < GraphqlRails::Model
112
+
113
+ false
114
+ end
115
+
80
116
  def unwrap_type(type)
81
117
  unwrappable = type
82
118
  unwrappable = unwrappable.of_type while wrapped_type?(unwrappable)
@@ -51,7 +51,9 @@ module GraphqlRails
51
51
  def paginated_type_arg
52
52
  return graphql_model.graphql.connection_type if graphql_model
53
53
 
54
- raise NotSupportedFeature, 'pagination is only supported for models which include GraphqlRails::Model'
54
+ error_message = "Unable to paginate #{unparsed_type.inspect}. " \
55
+ 'Pagination is only supported for models which include GraphqlRails::Model'
56
+ raise NotSupportedFeature, error_message
55
57
  end
56
58
 
57
59
  def list_type_arg
@@ -107,14 +109,7 @@ module GraphqlRails
107
109
  end
108
110
 
109
111
  def type_by_name
110
- unwrapped_scalar_type || unwrapped_model_type || raise_not_supported_type_error
111
- end
112
-
113
- def unwrapped_model_type
114
- type_class = graphql_model
115
- return unless type_class
116
-
117
- type_class.graphql.graphql_type
112
+ unwrapped_scalar_type || graphql_type_object || raise_not_supported_type_error
118
113
  end
119
114
  end
120
115
  end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphqlRails
4
+ # Allows defining methods chained way
5
+ module ChainableOptions
6
+ NOT_SET = Object.new
7
+
8
+ # nodoc
9
+ module ClassMethods
10
+ def chainable_option(option_name, default: nil)
11
+ define_method(option_name) do |value = NOT_SET|
12
+ get_or_set_chainable_option(option_name, value, default: default)
13
+ end
14
+ end
15
+ end
16
+
17
+ def self.included(base)
18
+ base.extend(ClassMethods)
19
+ end
20
+
21
+ def initialize_copy(other)
22
+ super
23
+ @chainable_option = other.instance_variable_get(:@chainable_option).dup
24
+ end
25
+
26
+ def with(**options)
27
+ options.each do |method_name, args|
28
+ send_args = [method_name]
29
+ send_args << args if method(method_name).parameters.present?
30
+ public_send(*send_args)
31
+ end
32
+ self
33
+ end
34
+
35
+ private
36
+
37
+ def fetch_chainable_option(option_name, *default, &block)
38
+ @chainable_option.fetch(option_name.to_sym, *default, &block)
39
+ end
40
+
41
+ def get_or_set_chainable_option(option_name, value = NOT_SET, default: nil)
42
+ @chainable_option ||= {}
43
+ return fetch_chainable_option(option_name, default) if value == NOT_SET
44
+
45
+ @chainable_option[option_name.to_sym] = value
46
+ self
47
+ end
48
+ end
49
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'graphql_rails/controller/request'
4
+ require 'graphql_rails/types/argument_type'
4
5
 
5
6
  module GraphqlRails
6
7
  class Controller
@@ -8,6 +9,8 @@ module GraphqlRails
8
9
  # Resolver which includes controller specific methods.
9
10
  # Used to simplify resolver build for each controller action
10
11
  class ControllerActionResolver < GraphQL::Schema::Resolver
12
+ argument_class(GraphqlRails::Types::ArgumentType)
13
+
11
14
  def self.controller(controller_class = nil)
12
15
  @controller = controller_class if controller_class
13
16
  @controller
@@ -5,7 +5,7 @@ module GraphqlRails
5
5
  # wrapps active record relation and returns decorated object instead
6
6
  class RelationDecorator
7
7
  delegate :map, :each, to: :to_a
8
- delegate :limit_value, :offset_value, :count, :size, to: :relation
8
+ delegate :limit_value, :offset_value, :count, :size, :empty?, to: :relation
9
9
 
10
10
  def self.decorates?(object)
11
11
  (defined?(ActiveRecord) && object.is_a?(ActiveRecord::Relation)) ||
@@ -24,7 +24,7 @@ module GraphqlRails
24
24
  end
25
25
  end
26
26
 
27
- %i[first second last].each do |method_name|
27
+ %i[first second last find find_by].each do |method_name|
28
28
  define_method method_name do |*args, &block|
29
29
  decoratable_object_method(method_name, *args, &block)
30
30
  end
@@ -3,9 +3,14 @@
3
3
  module GraphqlRails
4
4
  # contains configuration options related with inputs
5
5
  module InputConfigurable
6
- def permit(*no_type_attributes, **typed_attributes)
7
- no_type_attributes.each { |attribute| permit_input(attribute) }
8
- typed_attributes.each { |attribute, type| permit_input(attribute, type: type) }
6
+ def permit(*args)
7
+ args.each do |arg|
8
+ if arg.is_a? Hash
9
+ arg.each { |attribute, type| permit_input(attribute, type: type) }
10
+ else
11
+ permit_input(arg)
12
+ end
13
+ end
9
14
  self
10
15
  end
11
16
 
@@ -37,11 +42,8 @@ module GraphqlRails
37
42
  end
38
43
 
39
44
  def build_input_attribute(name, options: {}, **other_options)
40
- Attributes::InputAttribute.new(
41
- name.to_s,
42
- options: input_attribute_options.merge(options),
43
- **other_options
44
- )
45
+ input_options = input_attribute_options.merge(options)
46
+ Attributes::InputAttribute.new(name.to_s, config: self).with(options: input_options, **other_options)
45
47
  end
46
48
  end
47
49
  end
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'graphql_rails/types/argument_type'
4
+ require 'graphql_rails/concerns/service'
5
+
3
6
  module GraphqlRails
4
7
  module Model
5
8
  # stores information about model specific config, like attributes and types
6
9
  class BuildGraphqlInputType
7
- require 'graphql_rails/concerns/service'
8
-
9
10
  include ::GraphqlRails::Service
10
11
 
11
12
  def initialize(name:, description: nil, attributes:)
@@ -20,6 +21,7 @@ module GraphqlRails
20
21
  type_attributes = attributes
21
22
 
22
23
  Class.new(GraphQL::Schema::InputObject) do
24
+ argument_class(GraphqlRails::Types::ArgumentType)
23
25
  graphql_name(type_name)
24
26
  description(type_description)
25
27
 
@@ -2,25 +2,47 @@
2
2
 
3
3
  module GraphqlRails
4
4
  module Model
5
- # contains methods which are shared between various configurations
6
- # expects `default_name` to be defined
5
+ # Contains methods which are shared between various configurations.
6
+ #
7
+ # Expects `default_name` to be defined.
8
+ # Expects `build_attribute(attr_name)` method to be defined.
7
9
  module Configurable
10
+ require 'active_support/concern'
11
+ require 'graphql_rails/concerns/chainable_options'
12
+
13
+ extend ActiveSupport::Concern
14
+
15
+ included do
16
+ include GraphqlRails::ChainableOptions
17
+
18
+ chainable_option :description
19
+ end
20
+
21
+ def initialize_copy(other)
22
+ super
23
+ @type_name = nil
24
+ @attributes = other.attributes.transform_values(&:dup)
25
+ end
26
+
8
27
  def attributes
9
28
  @attributes ||= {}
10
29
  end
11
30
 
12
- def name(graphql_name = nil)
13
- @name = graphql_name if graphql_name
14
- @name || default_name
31
+ def name(*args)
32
+ get_or_set_chainable_option(:name, *args) || default_name
15
33
  end
16
34
 
17
35
  def type_name
18
36
  @type_name ||= "#{name.camelize}Type#{SecureRandom.hex}"
19
37
  end
20
38
 
21
- def description(new_description = nil)
22
- @description = new_description if new_description
23
- @description
39
+ def attribute(attribute_name, **attribute_options)
40
+ key = attribute_name.to_s
41
+
42
+ attributes[key] ||= build_attribute(attribute_name).tap do |new_attribute|
43
+ new_attribute.with(**attribute_options) unless attribute_options.empty?
44
+ yield(new_attribute) if block_given?
45
+ end
24
46
  end
25
47
  end
26
48
  end
@@ -2,7 +2,6 @@
2
2
 
3
3
  require 'graphql_rails/attributes'
4
4
  require 'graphql_rails/model/find_or_build_graphql_type'
5
- require 'graphql_rails/model/build_enum_type'
6
5
  require 'graphql_rails/model/input'
7
6
  require 'graphql_rails/model/configurable'
8
7
  require 'graphql_rails/model/build_connection_type'
@@ -11,6 +10,7 @@ module GraphqlRails
11
10
  module Model
12
11
  # stores information about model specific config, like attributes and types
13
12
  class Configuration
13
+ include ChainableOptions
14
14
  include Configurable
15
15
 
16
16
  def initialize(model_class)
@@ -22,22 +22,14 @@ module GraphqlRails
22
22
  @connection_type = nil
23
23
  @graphql_type = nil
24
24
  @input = other.instance_variable_get(:@input)&.transform_values(&:dup)
25
- @attributes = other.instance_variable_get(:@attributes)&.transform_values(&:dup)
26
25
  end
27
26
 
28
27
  def attribute(attribute_name, **attribute_options)
29
28
  key = attribute_name.to_s
30
29
 
31
- attributes[key] ||= Attributes::Attribute.new(attribute_name)
32
-
33
- attributes[key].tap do |attribute|
34
- attribute_options.each do |method_name, args|
35
- send_args = [method_name]
36
- send_args << args if attribute.method(method_name).parameters.present?
37
- attribute.public_send(*send_args)
38
- end
39
-
40
- yield(attribute) if block_given?
30
+ attributes[key] ||= build_attribute(attribute_name).tap do |new_attribute|
31
+ new_attribute.with(**attribute_options)
32
+ yield(new_attribute) if block_given?
41
33
  end
42
34
  end
43
35
 
@@ -68,13 +60,35 @@ module GraphqlRails
68
60
  @connection_type ||= BuildConnectionType.call(graphql_type)
69
61
  end
70
62
 
63
+ def with_ensured_fields!
64
+ return self if @graphql_type.blank?
65
+
66
+ reset_graphql_type if attributes.any? && graphql_type.fields.length != attributes.length
67
+
68
+ self
69
+ end
70
+
71
71
  private
72
72
 
73
73
  attr_reader :model_class
74
74
 
75
+ def build_attribute(attribute_name)
76
+ Attributes::Attribute.new(attribute_name)
77
+ end
78
+
75
79
  def default_name
76
80
  @default_name ||= model_class.name.split('::').last
77
81
  end
82
+
83
+ def reset_graphql_type
84
+ @graphql_type = FindOrBuildGraphqlType.call(
85
+ name: name,
86
+ description: description,
87
+ attributes: attributes,
88
+ type_name: type_name,
89
+ force_define_attributes: true
90
+ )
91
+ end
78
92
  end
79
93
  end
80
94
  end
@@ -10,20 +10,21 @@ module GraphqlRails
10
10
 
11
11
  include ::GraphqlRails::Service
12
12
 
13
- def initialize(name:, description:, attributes:, type_name:)
13
+ def initialize(name:, description:, attributes:, type_name:, force_define_attributes: false)
14
14
  @name = name
15
15
  @description = description
16
16
  @attributes = attributes
17
17
  @type_name = type_name
18
+ @force_define_attributes = force_define_attributes
18
19
  end
19
20
 
20
21
  def call
21
- klass.tap { add_fields_to_graphql_type if new_class? }
22
+ klass.tap { add_fields_to_graphql_type if new_class? || force_define_attributes }
22
23
  end
23
24
 
24
25
  private
25
26
 
26
- attr_reader :name, :description, :attributes, :type_name
27
+ attr_reader :name, :description, :attributes, :type_name, :force_define_attributes
27
28
 
28
29
  delegate :klass, :new_class?, to: :type_class_finder
29
30
 
@@ -36,29 +37,30 @@ module GraphqlRails
36
37
  end
37
38
 
38
39
  def add_fields_to_graphql_type
39
- AddFieldsToGraphqlType.call(klass: klass, attributes: attributes.values.select(&:scalar_type?))
40
+ scalar_attributes, dynamic_attributes = attributes.values.partition(&:scalar_type?)
40
41
 
41
- attributes.values.reject(&:scalar_type?).tap do |dynamic_attributes|
42
- find_or_build_dynamic_graphql_types(dynamic_attributes) do |name, description, attributes, type_name|
43
- self.class.call(
44
- name: name, description: description,
45
- attributes: attributes, type_name: type_name
46
- )
47
- end
48
- AddFieldsToGraphqlType.call(klass: klass, attributes: dynamic_attributes)
49
- end
42
+ AddFieldsToGraphqlType.call(klass: klass, attributes: scalar_attributes)
43
+ dynamic_attributes.each { |attribute| find_or_build_dynamic_type(attribute) }
44
+ AddFieldsToGraphqlType.call(klass: klass, attributes: dynamic_attributes)
50
45
  end
51
46
 
52
- def find_or_build_dynamic_graphql_types(dynamic_attributes)
53
- dynamic_attributes.each do |attribute|
54
- yield(
55
- attribute.graphql_model.graphql.name,
56
- attribute.graphql_model.graphql.description,
57
- attribute.graphql_model.graphql.attributes,
58
- attribute.graphql_model.graphql.type_name
59
- )
47
+ def find_or_build_dynamic_type(attribute)
48
+ graphql_model = attribute.graphql_model
49
+ if graphql_model
50
+ find_or_build_graphql_model_type(graphql_model)
51
+ else
52
+ AddFieldsToGraphqlType.call(klass: klass, attributes: [attribute])
60
53
  end
61
54
  end
55
+
56
+ def find_or_build_graphql_model_type(graphql_model)
57
+ self.class.call(
58
+ name: graphql_model.graphql.name,
59
+ description: graphql_model.graphql.description,
60
+ attributes: graphql_model.graphql.attributes,
61
+ type_name: graphql_model.graphql.type_name
62
+ )
63
+ end
62
64
  end
63
65
  end
64
66
  end
@@ -5,6 +5,7 @@ module GraphqlRails
5
5
  # Initializes class to define graphql type and fields.
6
6
  class FindOrBuildGraphqlTypeClass
7
7
  require 'graphql_rails/concerns/service'
8
+ require 'graphql_rails/types/object_type'
8
9
 
9
10
  include ::GraphqlRails::Service
10
11
 
@@ -32,7 +33,7 @@ module GraphqlRails
32
33
  graphql_type_name = name
33
34
  graphql_type_description = description
34
35
 
35
- graphql_type_klass = Class.new(GraphQL::Schema::Object) do
36
+ graphql_type_klass = Class.new(GraphqlRails::Types::ObjectType) do
36
37
  graphql_name(graphql_type_name)
37
38
  description(graphql_type_description)
38
39
  end
@@ -1,58 +1,42 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'graphql_rails/model/build_graphql_input_type'
4
- require 'graphql_rails/model/configurable'
5
-
6
3
  module GraphqlRails
7
4
  module Model
8
5
  # stores information about model input specific config, like attributes and types
9
6
  class Input
7
+ require 'graphql_rails/concerns/chainable_options'
8
+ require 'graphql_rails/model/configurable'
9
+ require 'graphql_rails/model/build_graphql_input_type'
10
+
10
11
  include Configurable
11
12
 
13
+ chainable_option :enum
14
+
12
15
  def initialize(model_class, input_name_suffix)
13
16
  @model_class = model_class
14
17
  @input_name_suffix = input_name_suffix
15
18
  end
16
19
 
17
- def initialize_copy(other)
18
- super
19
- @attributes = other.instance_variable_get(:@attributes)&.transform_values(&:dup)
20
- end
21
-
22
20
  def graphql_input_type
23
21
  @graphql_input_type ||= BuildGraphqlInputType.call(
24
22
  name: name, description: description, attributes: attributes
25
23
  )
26
24
  end
27
25
 
28
- def attribute(attribute_name, type: nil, enum: nil, **attribute_options)
29
- input_type = attribute_type(attribute_name, type: type, enum: enum, **attribute_options)
30
-
31
- attributes[attribute_name.to_s] = Attributes::InputAttribute.new(
32
- attribute_name, type: input_type, **attribute_options
33
- )
34
- end
35
-
36
26
  private
37
27
 
38
28
  attr_reader :input_name_suffix, :model_class
39
29
 
30
+ def build_attribute(attribute_name)
31
+ Attributes::InputAttribute.new(attribute_name, config: self)
32
+ end
33
+
40
34
  def default_name
41
35
  @default_name ||= begin
42
36
  suffix = input_name_suffix ? input_name_suffix.to_s.camelize : ''
43
37
  "#{model_class.name.split('::').last}#{suffix}Input"
44
38
  end
45
39
  end
46
-
47
- def attribute_type(attribute_name, type:, enum:, description: nil, **_other)
48
- return type unless enum
49
-
50
- BuildEnumType.call(
51
- "#{name}_#{attribute_name}_enum",
52
- allowed_values: enum,
53
- description: description
54
- )
55
- end
56
40
  end
57
41
  end
58
42
  end
@@ -28,7 +28,7 @@ module GraphqlRails
28
28
 
29
29
  def graphql
30
30
  @graphql ||= Model::Configuration.new(self)
31
- yield(@graphql) if block_given?
31
+ @graphql.tap { |it| yield(it) }.with_ensured_fields! if block_given?
32
32
  @graphql
33
33
  end
34
34
  end