Read GraphQL field types from file instead of from database
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user