Module: Mongoid::Attributes::Dynamic

Extended by:
ActiveSupport::Concern
Defined in:
lib/mongoid/attributes/dynamic.rb

Overview

This module contains the behavior for dynamic attributes.

Since:

  • 4.0.0

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ 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.

Used for allowing accessor methods for dynamic attributes.

Examples:

Call through method_missing.

document.method_missing(:test)

Parameters:

  • name (String, Symbol)

    The name of the method.

  • *args (Array)

    The arguments to the method.

Returns:

  • (Object)

    The result of the method call.

Since:

  • 4.0.0



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# 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

Instance Method Details

#define_dynamic_before_type_cast_reader(name) ⇒ 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.

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

Examples:

Define a reader method for an attribute.

model.define_dynamic_before_type_cast_reader(:field)

Parameters:

  • name (String)

    The name of the field.

Since:

  • 4.0.0



58
59
60
61
62
63
64
65
# File 'lib/mongoid/attributes/dynamic.rb', line 58

def define_dynamic_before_type_cast_reader(name)
  class_eval <<-READER
    def #{name}_before_type_cast
      attribute_will_change!(#{name.inspect})
      read_attribute_before_type_cast(#{name.inspect})
    end
  READER
end

#define_dynamic_reader(name) ⇒ 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.

Define a reader method for a dynamic attribute.

Examples:

Define a reader method.

model.define_dynamic_reader(:field)

Parameters:

  • name (String)

    The name of the field.

Since:

  • 4.0.0



38
39
40
41
42
43
44
45
46
# File 'lib/mongoid/attributes/dynamic.rb', line 38

def define_dynamic_reader(name)
  return unless name.valid_method_name?
  class_eval <<-READER
    def #{name}
      attribute_will_change!(#{name.inspect})
      read_attribute(#{name.inspect})
    end
  READER
end

#define_dynamic_writer(name) ⇒ 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.

Define a writer method for a dynamic attribute.

Examples:

Define a writer method.

model.define_dynamic_writer(:field)

Parameters:

  • name (String)

    The name of the field.

Since:

  • 4.0.0



77
78
79
80
81
82
83
84
85
# File 'lib/mongoid/attributes/dynamic.rb', line 77

def define_dynamic_writer(name)
  return unless name.valid_method_name?

  class_eval <<-WRITER
    def #{name}=(value)
      write_attribute(#{name.inspect}, value)
    end
  WRITER
end

#inspect_dynamic_fieldsString

Get an array of inspected dynamic fields for the document.

Examples:

Inspect the dynamic fields.

document.inspect_dynamic_fields

Returns:

  • (String)

    An array of pretty printed dynamic field values.

Since:

  • 4.0.0



114
115
116
117
118
119
# 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

#process_attribute(name, value) ⇒ Object

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

Examples:

Process the attribute.

document.process_attribute(name, value)

Parameters:

  • name (Symbol)

    The name of the field.

  • value (Object)

    The value of the field.

Since:

  • 4.0.0



97
98
99
100
101
102
103
104
# 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) ⇒ true, false

Override respond_to? so it responds properly for dynamic attributes.

Examples:

Does this object respond to the method?

person.respond_to?(:title)

Parameters:

  • *args (Array)

    The name of the method.

Returns:

  • (true, false)

    True if it does, false if not.

Since:

  • 4.0.0



21
22
23
24
25
26
# 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