Skip to content

Commit 1f813e5

Browse files
committed
refactor(BaseType) unify logic for types that have possible types
1 parent 37fd47a commit 1f813e5

File tree

7 files changed

+36
-46
lines changed

7 files changed

+36
-46
lines changed

lib/graphql/base_type.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,35 @@ def unwrap
2626
end
2727
end
2828

29+
# Find out which possible type to use for `value`.
30+
# Returns self if there are no possible types (ie, not Union or Interface)
31+
def resolve_type(value)
32+
self
33+
end
34+
35+
module HasPossibleTypes
36+
# Return the implementing type for `object`.
37+
# The default implementation assumes that there's a type with the same name as `object.class.name`.
38+
# Maybe you'll need to override this in your own interfaces!
39+
#
40+
# @param object [Object] the object which needs a type to expose it
41+
# @return [GraphQL::ObjectType] the type which should expose `object`
42+
def resolve_type(object)
43+
instance_exec(object, &@resolve_type_proc)
44+
end
45+
46+
# The default implementation of {#resolve_type} gets `object.class.name`
47+
# and finds a type with the same name
48+
DEFAULT_RESOLVE_TYPE = -> (object) {
49+
type_name = object.class.name
50+
possible_types.find {|t| t.name == type_name}
51+
}
52+
53+
def resolve_type=(new_proc)
54+
@resolve_type_proc = new_proc || DEFAULT_RESOLVE_TYPE
55+
end
56+
end
57+
2958
# Print the human-readable name of this type
3059
def to_s
3160
Printer.instance.print(self)

lib/graphql/interface_type.rb

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,9 @@
1111
# end
1212
#
1313
class GraphQL::InterfaceType < GraphQL::BaseType
14+
include GraphQL::BaseType::HasPossibleTypes
1415
defined_by_config :name, :description, :fields, :resolve_type
15-
attr_accessor :name, :description, :fields, :resolve_type
16-
17-
# The default implementation of {#resolve_type} gets `object.class.name`
18-
# and finds a type with the same name
19-
DEFAULT_RESOLVE_TYPE = -> (object) {
20-
type_name = object.class.name
21-
possible_types.find {|t| t.name == type_name}
22-
}
16+
attr_accessor :name, :description, :fields
2317

2418
def kind
2519
GraphQL::TypeKinds::INTERFACE
@@ -29,18 +23,4 @@ def kind
2923
def possible_types
3024
@possible_types ||= []
3125
end
32-
33-
# Return the implementing type for `object`.
34-
# The default implementation assumes that there's a type with the same name as `object.class.name`.
35-
# Maybe you'll need to override this in your own interfaces!
36-
#
37-
# @param object [Object] the object which needs a type to expose it
38-
# @return [GraphQL::ObjectType] the type which should expose `object`
39-
def resolve_type(object)
40-
instance_exec(object, &@resolve_type_proc)
41-
end
42-
43-
def resolve_type=(new_proc)
44-
@resolve_type_proc = new_proc || DEFAULT_RESOLVE_TYPE
45-
end
4626
end

lib/graphql/query/base_execution/value_resolution.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class ListResolution < BaseResolution
3838
def result
3939
wrapped_type = field_type.of_type
4040
value.map do |item|
41-
resolved_type = wrapped_type.kind.resolve(wrapped_type, item)
41+
resolved_type = wrapped_type.resolve_type(item)
4242
strategy_class = get_strategy_for_kind(resolved_type.kind)
4343
inner_strategy = strategy_class.new(item, resolved_type, target, parent_type, ast_field, query, execution_strategy)
4444
inner_strategy.result
@@ -62,7 +62,7 @@ def result
6262
class NonNullResolution < BaseResolution
6363
def result
6464
wrapped_type = field_type.of_type
65-
resolved_type = wrapped_type.kind.resolve(wrapped_type, value)
65+
resolved_type = wrapped_type.resolve_type(value)
6666
strategy_class = get_strategy_for_kind(resolved_type.kind)
6767
inner_strategy = strategy_class.new(value, resolved_type, target, parent_type, ast_field, query, execution_strategy)
6868
inner_strategy.result

lib/graphql/query/serial_execution/field_resolution.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def get_finished_value(raw_value)
2222
if raw_value.nil?
2323
nil
2424
else
25-
resolved_type = field.type.kind.resolve(field.type, raw_value)
25+
resolved_type = field.type.resolve_type(raw_value)
2626
strategy_class = GraphQL::Query::BaseExecution::ValueResolution.get_strategy_for_kind(resolved_type.kind)
2727
result_strategy = strategy_class.new(raw_value, resolved_type, target, parent_type, ast_node, query, execution_strategy)
2828
result_strategy.result

lib/graphql/type_kinds.rb

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,6 @@ def input?; @input; end
2323
def to_s; @name; end
2424
# Is this TypeKind composed of many values?
2525
def composite?; @composite; end
26-
27-
# Get the implementing type for `value` from `type` (no-op for TypeKinds which don't `resolves?`)
28-
def resolve(type, value)
29-
if resolves?
30-
type.resolve_type(value)
31-
else
32-
type
33-
end
34-
end
3526
end
3627

3728
TYPE_KINDS = [

lib/graphql/union_type.rb

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,11 @@
99
# end
1010
#
1111
class GraphQL::UnionType < GraphQL::BaseType
12-
attr_accessor :name, :description, :possible_types, :resolve_type
12+
include GraphQL::BaseType::HasPossibleTypes
13+
attr_accessor :name, :description, :possible_types
1314
defined_by_config :name, :description, :possible_types, :resolve_type
1415

1516
def kind
1617
GraphQL::TypeKinds::UNION
1718
end
18-
19-
# @see {InterfaceType#resolve_type}
20-
def resolve_type(object)
21-
instance_exec(object, &@resolve_type_proc)
22-
end
23-
24-
def resolve_type=(new_proc)
25-
@resolve_type_proc = new_proc || GraphQL::InterfaceType::DEFAULT_RESOLVE_TYPE
26-
end
2719
end

readme.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,6 @@ If you're building a backend for [Relay](http://facebook.github.io/relay/), you'
9797
- Code clean-up
9898
- Raise if you try to configure an attribute which doesn't suit the type
9999
- ie, if you try to define `resolve` on an ObjectType, it should somehow raise
100-
- Make better inheritance between types
101-
- Also move `TypeKind#resolve` ?
102100
- Big ideas:
103101
- Cook up some path other than "n+1s everywhere"
104102
- See Sangria's `project` approach ([in progress](https://github.com/rmosolgo/graphql-ruby/pull/15))

0 commit comments

Comments
 (0)