module GraphQL::Rails::Mongoid

Mongoid type extension for the GraphQL type system.

Public Instance Methods

clear() click to toggle source

Clear internal state, probably due to a Rails reload.

# File lib/graphql/rails/extensions/mongoid.rb, line 17
def clear
  @types = nil
end
lookup(type_name, id) click to toggle source

Lookup an arbitrary object from its GraphQL type name and ID.

# File lib/graphql/rails/extensions/mongoid.rb, line 28
def lookup(type_name, id)
  return unless type_name.starts_with?(namespace)
  types.each_pair do |type, graph_type|
    return type.find(id) if graph_type.name == type_name
  end
  nil
end
resolve(type) click to toggle source

Resolve an arbitrary type to a GraphQL type. Returns nil if the type isn't a Mongoid document.

# File lib/graphql/rails/extensions/mongoid.rb, line 23
def resolve(type)
  types[type] || build_type(type)
end

Private Instance Methods

build_type(type) click to toggle source

Build a GraphQL type for a Mongoid document. Returns nil if the type isn't a Mongoid document.

# File lib/graphql/rails/extensions/mongoid.rb, line 59
def build_type(type)
  return nil unless type.included_modules.include?(::Mongoid::Document)
  Rails.logger.debug "Building Mongoid::Document type: #{type.name}"

  # Build and cache the GraphQL type.
  # TODO: Map type inheritance to GraphQL interfaces.
  type_name = Types.to_type_name(type.name, namespace)
  types[type] = GraphQL::ObjectType.define do
    name type_name

    # Add the global node ID, if enabled; otherwise, document ID.
    if Rails.config.global_ids
      interfaces [NodeIdentification.interface]
      global_id_field :id
    else
      field :id do
        type -> { Types.resolve(BSON::ObjectId) }
      end
    end

    # Add each field from the document.
    # TODO: Support field exclusion and renaming.
    type.fields.each_value do |field_value|
      field Types.to_field_name(field_value.name) do
        property field_value.name.to_sym
        type -> { Types.resolve(field_value.type) }
        description field_value.label unless field_value.label.blank?
      end
    end

    # Add each relationship from the document as a Relay connection.
    type.relations.each_value do |relationship|
      # TODO: Add polymorphic support.
      if relationship.polymorphic?
        Rails.logger.warn(
          "Skipping polymorphic relationship: #{relationship.name}"
        )
        next
      end

      # Check that relationship has a valid type.
      begin
        klass = relationship.klass
      rescue
        Rails.logger.warn(
          "Skipping relationship with invalid class: #{relationship.name}"
        )
        next
      end

      if relationship.many?
        connection Types.to_field_name(relationship.name) do
          property relationship.name.to_sym
          type -> { Types.resolve(klass).connection_type }
        end
      else
        field Types.to_field_name(relationship.name) do
          property relationship.name.to_sym
          type -> { Types.resolve(klass) }
        end
      end
    end
  end
end
namespace() click to toggle source

Namespace for Mongoid types, if namespaces are required.

# File lib/graphql/rails/extensions/mongoid.rb, line 39
def namespace
  if Types.use_namespaces?
    'MG'
  else
    ''
  end
end
types() click to toggle source

Cached mapping of Mongoid types to GraphQL types, initialized with mappings for common built-in scalar types.

# File lib/graphql/rails/extensions/mongoid.rb, line 49
def types
  @types ||= {
    Boolean => GraphQL::BOOLEAN_TYPE,
    ::Mongoid::Boolean => GraphQL::BOOLEAN_TYPE,
    BSON::ObjectId => GraphQL::STRING_TYPE,
  }
end