Read GraphQL field types from file instead of from database

This commit is contained in:
Alberto Miedes Garcés
2017-01-01 19:36:07 +01:00
parent 0f663603d0
commit 7dc4d80e7b
3 changed files with 120 additions and 45 deletions

View File

@@ -1,12 +1,13 @@
module GraphQL
class TypeCreator
# Return a GraphQL type for a 'database_type'
TYPES_CONVERSION = Hash.new(GraphQL::STRING_TYPE).merge(
SCALAR_TYPES = {
integer: GraphQL::INT_TYPE,
boolean: GraphQL::BOOLEAN_TYPE,
float: GraphQL::FLOAT_TYPE,
double: GraphQL::FLOAT_TYPE
)
double: GraphQL::FLOAT_TYPE,
string: GraphQL::STRING_TYPE
}
attr_accessor :created_types
@@ -14,7 +15,7 @@ module GraphQL
@created_types = {}
end
def create(model, field_names)
def create(model, fields)
type_creator = self
created_type = GraphQL::ObjectType.define do
@@ -23,41 +24,43 @@ module GraphQL
description("#{model.model_name.human}")
# Make a field for each column, association or method
field_names.each do |field_name|
if model.column_names.include?(field_name.to_s)
field(field_name.to_s, TYPES_CONVERSION[model.columns_hash[field_name.to_s].type])
else
association = type_creator.class.association?(model, field_name)
target_model = association.klass
public_elements = target_model.respond_to?(:public_for_api) ? target_model.public_for_api : target_model.all
if type_creator.class.needs_pagination?(association)
connection(association.name, -> { type_creator.created_types[target_model].connection_type }) do
resolve -> (object, arguments, context) do
object.send(association.name).all & public_elements.all
end
fields.each do |name, type|
case GraphQL::TypeCreator.type_kind(type)
when :scalar
field name, SCALAR_TYPES[type]
when :simple_association
field(name, -> { type_creator.created_types[type] }) do
resolve -> (object, arguments, context) do
target_public_elements = type.respond_to?(:public_for_api) ? type.public_for_api : type.all
wanted_element = object.send(name)
target_public_elements.include?(wanted_element) ? wanted_element : nil
end
else
field(association.name, -> { type_creator.created_types[target_model] }) do
resolve -> (object, arguments, context) do
linked_element = object.send(field_name)
public_elements.include?(linked_element) ? linked_element : nil
end
end
when :paginated_association
type = type.first
connection(name, -> { type_creator.created_types[type].connection_type }) do
resolve -> (object, arguments, context) do
target_public_elements = type.respond_to?(:public_for_api) ? type.public_for_api : type.all
object.send(name).all & target_public_elements.all
end
end
end
end
end
created_types[model] = created_type
return created_type # GraphQL::ObjectType
end
def self.association?(model, field_name)
model.reflect_on_all_associations.find { |a| a.name == field_name }
def self.type_kind(type)
if SCALAR_TYPES[type]
:scalar
elsif type.class == Class
:simple_association
elsif type.class == Array
:paginated_association
end
end
def self.needs_pagination?(association)
association.macro == :has_many
end
end
end