Project

General

Profile

Download (1.82 KB) Statistics
| Branch: | Tag: | Revision:
module Types
class BaseObject < GraphQL::Types::Relay::BaseObject
implements GraphQL::Relay::Node.interface

connection_type_class Connections::BaseConnection

class << self
def field(*args, **kwargs, &block)
null = kwargs.key?(:null) ? kwargs[:null] : nullable?(args.first)
super(*args, **kwargs.except(:null), null: null, &block)
end

def timestamps
field :created_at, GraphQL::Types::ISO8601DateTime
field :updated_at, GraphQL::Types::ISO8601DateTime
end

def has_many(name, type, resolver: nil)
if resolver
field name, type.connection_type, resolver: resolver
else
field name, type.connection_type,
resolve: proc { |object| CollectionLoader.for(object.class, name).load(object) }
end
end

def belongs_to(name, type, resolver: nil)
if resolver
field name, type, resolver: resolver
else
field name, type,
resolve: (proc do |object|
foreign_key = object.class.reflect_on_association(name).foreign_key
RecordLoader.for(type.model_class).load(object.send(foreign_key))
end)
end
end

def model_class
"::#{self.to_s.demodulize}".safe_constantize
end

private

def nullable?(attribute)
return false if model_class.columns_hash[attribute.to_s]&.null == false

return false if model_class.validators_on(attribute).find do |v|
v.is_a?(ActiveModel::Validations::PresenceValidator) && v.options.none? { |o| [:if, :unless].include?(o) }
end

reflection = model_class.reflect_on_association(attribute)
return false if reflection && reflection.macro == :belongs_to && nullable?(reflection.foreign_key)

true
end
end
end
end
(5-5/24)