Module: Graphoid::MongoidDriver

Defined in:
lib/graphoid/drivers/mongoid.rb

Overview

module that helps executing mongoid specific code

Class Method Summary collapse

Class Method Details

.belongs_to?(type) ⇒ Boolean

Returns:

  • (Boolean)


43
44
45
46
# File 'lib/graphoid/drivers/mongoid.rb', line 43

def belongs_to?(type)
  type == mongo_constants[:belongs_to]
  
end

.class_of(relation) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
# 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) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/graphoid/drivers/mongoid.rb', line 117

def eager_load(selection, model)
  referenced_relations = [
    mongo_constants[:many_to_many],
    mongo_constants[:has_many],
    mongo_constants[:has_one],
    mongo_constants[:belongs_to]
  ]

  properties = Graphoid::Queries::Processor.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?(association.relation)

    subselection = properties[name.to_s.camelize(:lower)]
    children = Utils.symbolize(Graphoid::Queries::Processor.children_of(subselection))
    relations = relation.class_name.constantize.reflections.values.map(&:name)

    if (relations & children).empty?
      model = model.includes(name)
    else
      model = model.includes(name, with: ->(instance) { Graphoid::Queries::Processor.eager_load(subselection, instance) })
    end
  end

  model
end

.embedded_in?(type) ⇒ Boolean

Returns:

  • (Boolean)


60
61
62
# File 'lib/graphoid/drivers/mongoid.rb', line 60

def embedded_in?(type)
  type == mongo_constants[:embedded_in]
end

.embeds_many?(type) ⇒ Boolean

Returns:

  • (Boolean)


56
57
58
# File 'lib/graphoid/drivers/mongoid.rb', line 56

def embeds_many?(type)
  type == mongo_constants[:embeds_many]
end

.embeds_one?(type) ⇒ Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/graphoid/drivers/mongoid.rb', line 52

def embeds_one?(type)
  type == mongo_constants[:embeds_one]
end

.execute_and(scope, parsed) ⇒ Object



146
147
148
# File 'lib/graphoid/drivers/mongoid.rb', line 146

def execute_and(scope, parsed)
  scope.and(parsed)
end

.execute_or(scope, list) ⇒ Object



150
151
152
153
154
155
# File 'lib/graphoid/drivers/mongoid.rb', line 150

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) ⇒ Object



101
102
103
# 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) ⇒ Boolean

Returns:

  • (Boolean)


35
36
37
# 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) ⇒ Boolean

Returns:

  • (Boolean)


39
40
41
# File 'lib/graphoid/drivers/mongoid.rb', line 39

def has_many?(type)
  type == mongo_constants[:has_many]
end

.has_one?(type) ⇒ Boolean

Returns:

  • (Boolean)


48
49
50
# File 'lib/graphoid/drivers/mongoid.rb', line 48

def has_one?(type)
  type == mongo_constants[:has_one]
end

.inverse_name_of(relation) ⇒ Object



97
98
99
# File 'lib/graphoid/drivers/mongoid.rb', line 97

def inverse_name_of(relation)
  relation.inverse_of
end

.mongo_constantsObject



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 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) ⇒ Object



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/graphoid/drivers/mongoid.rb', line 157

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) ⇒ Object



180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/graphoid/drivers/mongoid.rb', line 180

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) ⇒ Object



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/graphoid/drivers/mongoid.rb', line 208

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) ⇒ Object



195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/graphoid/drivers/mongoid.rb', line 195

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) ⇒ Object



113
114
115
# File 'lib/graphoid/drivers/mongoid.rb', line 113

def relation_type(relation)
  relation.relation
end

.relations_of(model) ⇒ Object



105
106
107
# File 'lib/graphoid/drivers/mongoid.rb', line 105

def relations_of(model)
  model.relations
end

.skip(result, skip) ⇒ Object



109
110
111
# File 'lib/graphoid/drivers/mongoid.rb', line 109

def skip(result, skip)
  result.skip(skip)
end

.through?(_type) ⇒ Boolean

Returns:

  • (Boolean)


7
8
9
# File 'lib/graphoid/drivers/mongoid.rb', line 7

def through?(_type)
  false
end

.types_mapObject



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# 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