module Mongoid::Attributes::Dynamic

This module contains the behavior for dynamic attributes.

@since 4.0.0

Public Instance Methods

define_dynamic_before_type_cast_reader(name) click to toggle source

Define a reader method for a dynamic attribute before type cast.

@api private

@example Define a reader method for an attribute.

model.define_dynamic_before_type_cast_reader(:field)

@param [ String ] name The name of the field.

@since 4.0.0

# File lib/mongoid/attributes/dynamic.rb, line 58
      def define_dynamic_before_type_cast_reader(name)
        class_eval <<-READER, __FILE__, __LINE__ + 1
          def #{name}_before_type_cast
            attribute_will_change!(#{name.inspect})
            read_attribute_before_type_cast(#{name.inspect})
          end
        READER
      end
define_dynamic_reader(name) click to toggle source

Define a reader method for a dynamic attribute.

@api private

@example Define a reader method.

model.define_dynamic_reader(:field)

@param [ String ] name The name of the field.

@since 4.0.0

# File lib/mongoid/attributes/dynamic.rb, line 38
      def define_dynamic_reader(name)
        return unless name.valid_method_name?
        class_eval <<-READER, __FILE__, __LINE__ + 1
          def #{name}
            attribute_will_change!(#{name.inspect})
            read_attribute(#{name.inspect})
          end
        READER
      end
define_dynamic_writer(name) click to toggle source

Define a writer method for a dynamic attribute.

@api private

@example Define a writer method.

model.define_dynamic_writer(:field)

@param [ String ] name The name of the field.

@since 4.0.0

# File lib/mongoid/attributes/dynamic.rb, line 77
      def define_dynamic_writer(name)
        return unless name.valid_method_name?

        class_eval <<-WRITER, __FILE__, __LINE__ + 1
          def #{name}=(value)
            write_attribute(#{name.inspect}, value)
          end
        WRITER
      end
inspect_dynamic_fields() click to toggle source

Get an array of inspected dynamic fields for the document.

@example Inspect the dynamic fields.

document.inspect_dynamic_fields

@return [ String ] An array of pretty printed dynamic field values.

@since 4.0.0

# File lib/mongoid/attributes/dynamic.rb, line 114
def inspect_dynamic_fields
  keys = attributes.keys - fields.keys - relations.keys - ["_id", "_type"]
  return keys.map do |name|
    "#{name}: #{attributes[name].inspect}"
  end
end
method_missing(name, *args) click to toggle source

Used for allowing accessor methods for dynamic attributes.

@api private

@example Call through method_missing.

document.method_missing(:test)

@param [ String, Symbol ] name The name of the method. @param [ Array ] *args The arguments to the method.

@return [ Object ] The result of the method call.

@since 4.0.0

Calls superclass method
# File lib/mongoid/attributes/dynamic.rb, line 134
def method_missing(name, *args)
  attr = name.to_s
  return super unless attributes.has_key?(attr.reader)
  if attr.writer?
    getter = attr.reader
    define_dynamic_writer(getter)
    write_attribute(getter, args.first)
  elsif attr.before_type_cast?
    define_dynamic_before_type_cast_reader(attr.reader)
    attribute_will_change!(attr.reader)
    read_attribute_before_type_cast(attr.reader)
  else
    getter = attr.reader
    define_dynamic_reader(getter)
    attribute_will_change!(attr.reader)
    read_attribute(getter)
  end
end
process_attribute(name, value) click to toggle source

If the attribute is dynamic, add a field for it with a type of object and set the value.

@example Process the attribute.

document.process_attribute(name, value)

@param [ Symbol ] name The name of the field. @param [ Object ] value The value of the field.

@since 4.0.0

# File lib/mongoid/attributes/dynamic.rb, line 97
def process_attribute(name, value)
  responds = respond_to?("#{name}=")
  if !responds
    write_attribute(name, value)
  else
    send("#{name}=", value)
  end
end
respond_to?(name, include_private = false) click to toggle source

Override respond_to? so it responds properly for dynamic attributes.

@example Does this object respond to the method?

person.respond_to?(:title)

@param [ Array ] *args The name of the method.

@return [ true, false ] True if it does, false if not.

@since 4.0.0

Calls superclass method
# File lib/mongoid/attributes/dynamic.rb, line 21
def respond_to?(name, include_private = false)
  super || (
    attributes &&
    attributes.has_key?(name.to_s.reader)
  )
end