module Graphoid::MongoidDriver

module that helps executing mongoid specific code

Public Class Methods

belongs_to?(type) click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 43
def belongs_to?(type)
  type == mongo_constants[:belongs_to]
  
end
class_of(relation) click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 85
def class_of(relation)
  {
    mongo_constants[:many_to_many]  => ManyToMany,
    mongo_constants[:has_many]      => HasMany,
    mongo_constants[:has_one]       => HasOne,
    mongo_constants[:belongs_to]    => BelongsTo,
    mongo_constants[:embeds_many]   => EmbedsMany,
    mongo_constants[:embeds_one]    => EmbedsOne,
    mongo_constants[:embedded_in]   => Relation
  }[relation.relation] || Relation
end
eager_load(selection, model, first = true) click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 117
def eager_load(selection, model, first = true)
  referenced_relations = [
    mongo_constants[:many_to_many],
    mongo_constants[:has_many],
    mongo_constants[:has_one],
    mongo_constants[:belongs_to]
  ]

  properties = first ? Utils.first_children_of(selection) : Utils.children_of(selection)
  inclusions = Utils.symbolize(properties)

  Relation.relations_of(model).each do |name, relation|
    name = relation.name
    next if inclusions.exclude?(name) || referenced_relations.exclude?(relation.relation)

    subselection = properties[name.to_s.camelize(:lower)]
    subproperties = Utils.children_of(subselection)
    subchildren = Utils.symbolize(subproperties)
    subrelations = relation.class_name.constantize.relations.values.map(&:name)

    if (subrelations & subchildren).empty?
      model = model.includes(name)
    else
      begin
        gem "mongoid_includes"
        model = model.includes(name, with: ->(instance) { eager_load(subselection, instance, false) })
      rescue Gem::LoadError
        model = model.includes(name)
      end
    end
  end

  model
end
embedded_in?(type) click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 60
def embedded_in?(type)
  type == mongo_constants[:embedded_in]
end
embeds_many?(type) click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 56
def embeds_many?(type)
  type == mongo_constants[:embeds_many]
end
embeds_one?(type) click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 52
def embeds_one?(type)
  type == mongo_constants[:embeds_one]
end
execute_and(scope, parsed) click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 152
def execute_and(scope, parsed)
  scope.and(parsed)
end
execute_or(scope, list) click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 156
def execute_or(scope, list)
  list.map! do |object|
    Graphoid::Queries::Processor.execute(scope, object).selector
  end
  scope.any_of(list)
end
fields_of(model) click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 101
def fields_of(model)
  model.respond_to?(:fields) ? model.fields.values : []
end
has_and_belongs_to_many?(type) click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 35
def has_and_belongs_to_many?(type)
  type == mongo_constants[:many_to_many]
end
has_many?(type) click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 39
def has_many?(type)
  type == mongo_constants[:has_many]
end
has_one?(type) click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 48
def has_one?(type)
  type == mongo_constants[:has_one]
end
inverse_name_of(relation) click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 97
def inverse_name_of(relation)
  relation.inverse_of
end
mongo_constants() click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 11
def mongo_constants
  begin
    {
      many_to_many: Mongoid::Relations::Referenced::ManyToMany,
      has_many:     Mongoid::Relations::Referenced::Many,
      belongs_to:   Mongoid::Relations::Referenced::In,
      has_one:      Mongoid::Relations::Referenced::One,
      embeds_one:   Mongoid::Relations::Embedded::One,
      embeds_many:  Mongoid::Relations::Embedded::Many,
      embedded_in:  Mongoid::Relations::Embedded::In
    }
  rescue
    {
      many_to_many: Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy,
      has_many:     Mongoid::Association::Referenced::HasMany::Proxy,
      belongs_to:   Mongoid::Association::Referenced::BelongsTo::Proxy,
      has_one:      Mongoid::Association::Referenced::HasOne::Proxy,
      embeds_one:   Mongoid::Association::Embedded::EmbedsOne::Proxy,
      embeds_many:  Mongoid::Association::Embedded::EmbedsMany::Proxy,
      embedded_in:  Mongoid::Association::Embedded::EmbeddedIn::Proxy
    }
  end
end
parse(attribute, value, operator, prefix = nil) click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 163
def parse(attribute, value, operator, prefix = nil)
  field = attribute.name
  field = "#{prefix}.#{field}" if prefix
  parsed = {}
  case operator
  when 'gt', 'gte', 'lt', 'lte', 'in', 'nin'
    parsed[field.to_sym.send(operator)] = value
  when 'regex'
    parsed[field.to_sym] = Regexp.new(value.to_s, Regexp::IGNORECASE)
  when 'contains'
    parsed[field.to_sym] = Regexp.new(Regexp.quote(value.to_s), Regexp::IGNORECASE)
  when 'not'
    if value.present? && !value.is_a?(Numeric)
      parsed[field.to_sym.send(operator)] = Regexp.new(Regexp.quote(value.to_s), Regexp::IGNORECASE)
    else
      parsed[field.to_sym.send(:nin)] = [value]
    end
  else
    parsed[field.to_sym] = value
  end
  parsed
end
relate_embedded(scope, relation, filters) click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 186
def relate_embedded(scope, relation, filters)
  # TODO: this way of fetching this is not recursive as the regular fields
  # because the structure of the query is embeeded.field = value
  # we need more brain cells on this problem because it does not allow
  # to filter things using OR/AND
  parsed = {}
  filters.each do |key, value|
    operation = Operation.new(scope, key, value)
    attribute = OpenStruct.new(name: "#{relation.name}.#{operation.operand}")
    obj = parse(attribute, value, operation.operator).first
    parsed[obj[0]] = obj[1]
  end
  parsed
end
relate_many(scope, relation, value, operator) click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 214
def relate_many(scope, relation, value, operator)
  field_name = relation.inverse_name || scope.name.underscore
  target = Graphoid::Queries::Processor.execute(relation.klass, value).to_a

  if relation.embeds_many?
    # TODO: not implemented at all.
  end

  if relation.many_to_many?
    field_name = field_name.to_s.singularize + '_ids'
    ids = target.map(&field_name.to_sym)
    ids.flatten!.uniq!
  else
    field_name = field_name.to_s + '_id'
    ids = target.map(&field_name.to_sym)
  end

  parsed = {}
  if operator == 'none'
    parsed[:id.nin] = ids
  elsif operator == 'some'
    parsed[:id.in] = ids
  elsif operator == 'every'
    # missing implementation
  end
  parsed
end
relate_one(scope, relation, value) click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 201
def relate_one(scope, relation, value)
  field = relation.name
  parsed = {}

  parsed = relate_embedded(scope, relation, value) if relation.embeds_one?

  parsed = relation.exec(scope, value) if relation.belongs_to?

  parsed = relation.exec(scope, value) if relation.has_one?

  parsed
end
relation_type(relation) click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 113
def relation_type(relation)
  relation.relation
end
relations_of(model) click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 105
def relations_of(model)
  model.relations
end
skip(result, skip) click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 109
def skip(result, skip)
  result.skip(skip)
end
through?(_type) click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 7
def through?(_type)
  false
end
types_map() click to toggle source
# File lib/graphoid/drivers/mongoid.rb, line 64
def types_map
  {
    BSON::ObjectId => GraphQL::Types::ID,
    Mongoid::Boolean => GraphQL::Types::Boolean,
    # Graphoid::Upload => ApolloUploadServer::Upload,

    Boolean => GraphQL::Types::Boolean,
    Float => GraphQL::Types::Float,
    Integer => GraphQL::Types::Int,
    String => GraphQL::Types::String,
    Object => GraphQL::Types::String,
    Symbol => GraphQL::Types::String,

    DateTime => Graphoid::Scalars::DateTime,
    Time => Graphoid::Scalars::DateTime,
    Date => Graphoid::Scalars::DateTime,
    Array => Graphoid::Scalars::Array,
    Hash => Graphoid::Scalars::Hash
  }
end