Class: Mongoid::Attributes::Projector Private

Inherits:
Object
  • Object
show all
Defined in:
build/mongoid-7.3/lib/mongoid/attributes/projector.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

This module defines projection helpers.

Projection rules are rather non-trivial. See docs.mongodb.com/manual/reference/method/db.collection.find/#find-projection for server documentation. 4.4 server (and presumably all older ones) requires that a projection for content fields is either exclusionary or inclusionary, i.e. one cannot mix exclusions and inclusions in the same query. However, _id can be excluded in a projection that includes content fields. Integer projection values other than 0 and 1 aren’t officially documented as of this writing; see DOCSP-15266. 4.4 server also allows nested hash projection specification in addition to dot notation, which I assume Mongoid doesn’t handle yet.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(projection) ⇒ Projector

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Projector.



24
25
26
27
28
29
30
31
32
33
# File 'build/mongoid-7.3/lib/mongoid/attributes/projector.rb', line 24

def initialize(projection)
  if projection
    @content_projection = projection.dup
    @content_projection.delete('_id')
    @id_projection_value = projection['_id']
  else
    @content_projection = nil
    @id_projection_value = nil
  end
end

Instance Attribute Details

#content_projectionObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



36
37
38
# File 'build/mongoid-7.3/lib/mongoid/attributes/projector.rb', line 36

def content_projection
  @content_projection
end

#id_projection_valueObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



35
36
37
# File 'build/mongoid-7.3/lib/mongoid/attributes/projector.rb', line 35

def id_projection_value
  @id_projection_value
end

Instance Method Details

#attribute_or_path_allowed?(name) ⇒ true, false

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Determine if the specified attribute, or a dot notation path, is allowed by the configured projection, if any.

If there is no configured projection, returns true.

Parameters:

  • name (String)

    The name of the attribute or a dot notation path.

Returns:

  • (true, false)

    Whether the attribute is allowed by projection.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'build/mongoid-7.3/lib/mongoid/attributes/projector.rb', line 48

def attribute_or_path_allowed?(name)
  # Special handling for _id.
  if name == '_id'
    result = unless id_projection_value.nil?
      value_inclusionary?(id_projection_value)
    else
      true
    end
    return result
  end

  if content_projection.nil?
    # No projection (as opposed to an empty projection).
    # All attributes are allowed.
    return true
  end

  # Find an item which matches or is a parent of the requested name/path.
  # This handles the case when, for example, the projection was
  # {foo: true} and we want to know if foo.bar is allowed.
  item, value = content_projection.detect do |path, value|
    (name + '.').start_with?(path + '.')
  end
  if item
    return value_inclusionary?(value)
  end

  if content_inclusionary?
    # Find an item which would be a strict child of the requested name/path.
    # This handles the case when, for example, the projection was
    # {"foo.bar" => true} and we want to know if foo is allowed.
    # (It is as a container of bars.)
    item, value = content_projection.detect do |path, value|
      (path + '.').start_with?(name + '.')
    end
    if item
      return true
    end
  end

  !content_inclusionary?
end