Module: Mongoid::Attributes

Extended by:
ActiveSupport::Concern
Includes:
Nested, Processing, Readonly
Included in:
Composable
Defined in:
lib/mongoid/attributes.rb,
lib/mongoid/attributes/nested.rb,
lib/mongoid/attributes/dynamic.rb,
lib/mongoid/attributes/embedded.rb,
lib/mongoid/attributes/readonly.rb,
lib/mongoid/attributes/projector.rb,
lib/mongoid/attributes/processing.rb

Overview

This module contains the logic for handling the internal attributes hash, and how to get and set values.

Defined Under Namespace

Modules: ClassMethods, Dynamic, Embedded, Nested, Processing, Readonly Classes: Projector

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Readonly

#attribute_writable?

Methods included from Processing

#process_attributes

Instance Attribute Details

#attributesObject (readonly) Also known as: raw_attributes

Returns the value of attribute attributes.



22
23
24
# File 'lib/mongoid/attributes.rb', line 22

def attributes
  @attributes
end

Instance Method Details

#assign_attributes(attrs = nil) ⇒ Object

Allows you to set all the attributes for a particular mass-assignment security role by passing in a hash of attributes with keys matching the attribute names (which again matches the column names) and the role name using the :as option. To bypass mass-assignment security you can use the :without_protection => true option.

Examples:

Assign the attributes.

person.assign_attributes(:title => "Mr.")

Assign the attributes (with a role).

person.assign_attributes({ :title => "Mr." }, :as => :admin)

Parameters:

  • attrs (Hash) (defaults to: nil)

    The new attributes to set.



218
219
220
221
222
# File 'lib/mongoid/attributes.rb', line 218

def assign_attributes(attrs = nil)
  _assigning do
    process_attributes(attrs)
  end
end

#attribute_missing?(name) ⇒ true | false

Determine if the attribute is missing from the document, due to loading it from the database with missing fields.

Examples:

Is the attribute missing?

document.attribute_missing?("test")

Parameters:

  • name (String)

    The name of the attribute.

Returns:

  • (true | false)

    If the attribute is missing.



249
250
251
# File 'lib/mongoid/attributes.rb', line 249

def attribute_missing?(name)
  !Projector.new(__selected_fields).attribute_or_path_allowed?(name)
end

#attribute_present?(name) ⇒ true | false

Determine if an attribute is present.

Examples:

Is the attribute present?

person.attribute_present?("title")

Parameters:

  • name (String | Symbol)

    The name of the attribute.

Returns:

  • (true | false)

    True if present, false if not.



33
34
35
36
37
38
# File 'lib/mongoid/attributes.rb', line 33

def attribute_present?(name)
  attribute = read_raw_attribute(name)
  !attribute.blank? || attribute == false
rescue Mongoid::Errors::AttributeNotLoaded
  false
end

#attributes_before_type_castHash

Get the attributes that have not been cast.

Examples:

Get the attributes before type cast.

document.attributes_before_type_cast

Returns:

  • (Hash)

    The uncast attributes.



46
47
48
# File 'lib/mongoid/attributes.rb', line 46

def attributes_before_type_cast
  @attributes_before_type_cast ||= {}
end

#has_attribute?(name) ⇒ true | false

Does the document have the provided attribute?

Examples:

Does the document have the attribute?

model.has_attribute?(:name)

Parameters:

  • name (String | Symbol)

    The name of the attribute.

Returns:

  • (true | false)

    If the key is present in the attributes.



58
59
60
# File 'lib/mongoid/attributes.rb', line 58

def has_attribute?(name)
  attributes.key?(name.to_s)
end

#has_attribute_before_type_cast?(name) ⇒ true | false

Does the document have the provided attribute before it was assigned and type cast?

Examples:

Does the document have the attribute before it was assigned?

model.has_attribute_before_type_cast?(:name)

Parameters:

  • name (String | Symbol)

    The name of the attribute.

Returns:

  • (true | false)

    If the key is present in the attributes_before_type_cast.



72
73
74
# File 'lib/mongoid/attributes.rb', line 72

def has_attribute_before_type_cast?(name)
  attributes_before_type_cast.key?(name.to_s)
end

#process_raw_attribute(name, raw, field) ⇒ Object

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.

Process the raw attribute values just read from the documents attributes.

Parameters:

  • name (String)

    The name of the attribute to get.

  • raw (Object)

    The raw attribute value.

  • field (Field | nil)

    The field to use for demongoization or nil.

Returns:

  • (Object)

    The value of the attribute.



105
106
107
108
109
# File 'lib/mongoid/attributes.rb', line 105

def process_raw_attribute(name, raw, field)
  value = field ? field.demongoize(raw) : raw
  attribute_will_change!(name) if value.resizable?
  value
end

#read_attribute(name) ⇒ Object Also known as: []

Read a value from the document attributes. If the value does not exist it will return nil.

Examples:

Read an attribute.

person.read_attribute(:title)

Read an attribute (alternate syntax.)

person[:title]

Parameters:

  • name (String | Symbol)

    The name of the attribute to get.

Returns:

  • (Object)

    The value of the attribute.



88
89
90
91
92
# File 'lib/mongoid/attributes.rb', line 88

def read_attribute(name)
  field = fields[name.to_s]
  raw = read_raw_attribute(name)
  process_raw_attribute(name.to_s, raw, field)
end

#read_attribute_before_type_cast(name) ⇒ Object

Read a value from the attributes before type cast. If the value has not yet been assigned then this will return the attribute’s existing value using read_raw_attribute.

Examples:

Read an attribute before type cast.

person.read_attribute_before_type_cast(:price)

Parameters:

  • name (String | Symbol)

    The name of the attribute to get.

Returns:

  • (Object)

    The value of the attribute before type cast, if available. Otherwise, the value of the attribute.



122
123
124
125
126
127
128
129
# File 'lib/mongoid/attributes.rb', line 122

def read_attribute_before_type_cast(name)
  attr = name.to_s
  if attributes_before_type_cast.key?(attr)
    attributes_before_type_cast[attr]
  else
    read_raw_attribute(attr)
  end
end

#remove_attribute(name) ⇒ Object

Remove a value from the Document attributes. If the value does not exist it will fail gracefully.

Examples:

Remove the attribute.

person.remove_attribute(:title)

Parameters:

  • name (String | Symbol)

    The name of the attribute to remove.

Raises:



141
142
143
144
145
146
147
148
149
150
# File 'lib/mongoid/attributes.rb', line 141

def remove_attribute(name)
  validate_writable_field_name!(name.to_s)
  as_writable_attribute!(name) do |access|
    _assigning do
      attribute_will_change!(access)
      delayed_atomic_unsets[atomic_attribute_name(access)] = [] unless new_record?
      attributes.delete(access)
    end
  end
end

#typed_attributesObject

Return type-casted attributes.

Examples:

Type-casted attributes.

document.typed_attributes

Returns:

  • (Object)

    The hash with keys and values of the type-casted attributes.



259
260
261
# File 'lib/mongoid/attributes.rb', line 259

def typed_attributes
  attribute_names.map { |name| [name, send(name)] }.to_h
end

#write_attribute(name, value) ⇒ Object Also known as: []=

Write a single attribute to the document attribute hash. This will also fire the before and after update callbacks, and perform any necessary typecasting.

Examples:

Write the attribute.

person.write_attribute(:title, "Mr.")

Write the attribute (alternate syntax.)

person[:title] = "Mr."

Parameters:

  • name (String | Symbol)

    The name of the attribute to update.

  • value (Object)

    The value to set for the attribute.



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/mongoid/attributes.rb', line 164

def write_attribute(name, value)
  validate_writable_field_name!(name.to_s)

  field_name = database_field_name(name)

  if attribute_missing?(field_name)
    raise Mongoid::Errors::AttributeNotLoaded.new(self.class, field_name)
  end

  if attribute_writable?(field_name)
    _assigning do
      localized = fields[field_name].try(:localized?)
      attributes_before_type_cast[name.to_s] = value
      typed_value = typed_value_for(field_name, value)
      unless attributes[field_name] == typed_value || attribute_changed?(field_name)
        attribute_will_change!(field_name)
      end
      if localized
        present = fields[field_name].try(:localize_present?)
        loc_key, loc_val = typed_value.first
        if present && loc_val.blank?
          attributes[field_name]&.delete(loc_key)
        else
          attributes[field_name] ||= {}
          attributes[field_name].merge!(typed_value)
        end
      else
        attributes[field_name] = typed_value
      end

      # when writing an attribute, also remove it from the unsets,
      # so that removing then writing doesn't result in a removal.
      delayed_atomic_unsets.delete(field_name)

      typed_value
    end
  else
    # TODO: MONGOID-5072
  end
end

#write_attributes(attrs = nil) ⇒ Object Also known as: attributes=

Writes the supplied attributes hash to the document. This will only overwrite existing attributes if they are present in the new Hash, all others will be preserved.

Examples:

Write the attributes.

person.write_attributes(:title => "Mr.")

Write the attributes (alternate syntax.)

person.attributes = { :title => "Mr." }

Parameters:

  • attrs (Hash) (defaults to: nil)

    The new attributes to set.



235
236
237
# File 'lib/mongoid/attributes.rb', line 235

def write_attributes(attrs = nil)
  assign_attributes(attrs)
end