Module: Mongoid::Attributes::Dynamic

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

Overview

This module contains the behavior for dynamic attributes.

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 (Object...)

    The arguments to the method.

Returns:

  • (Object)

    The result of the method call.



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/mongoid/attributes/dynamic.rb', line 122

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_raw_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.



54
55
56
57
58
59
60
61
# File 'lib/mongoid/attributes/dynamic.rb', line 54

def define_dynamic_before_type_cast_reader(name)
  class_eval do
    define_method("#{name}_before_type_cast") do
      attribute_will_change!(name)
      read_attribute_before_type_cast(name)
    end
  end
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.



35
36
37
38
39
40
41
42
43
44
# File 'lib/mongoid/attributes/dynamic.rb', line 35

def define_dynamic_reader(name)
  return unless name.valid_method_name?

  class_eval do
    define_method(name) do
      attribute_will_change!(name)
      read_raw_attribute(name)
    end
  end
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.



71
72
73
74
75
76
77
78
79
# File 'lib/mongoid/attributes/dynamic.rb', line 71

def define_dynamic_writer(name)
  return unless name.valid_method_name?

  class_eval do
    define_method("#{name}=") do |value|
      write_attribute(name, value)
    end
  end
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.



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

def inspect_dynamic_fields
  keys = attributes.keys - fields.keys - relations.keys - ["_id", self.class.discriminator_key]
  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.



89
90
91
92
93
94
95
96
# File 'lib/mongoid/attributes/dynamic.rb', line 89

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:

  • name (Array)

    The name of the method.

  • include_private (true | false) (defaults to: false)

Returns:

  • (true | false)

    True if it does, false if not.



20
21
22
23
24
25
# File 'lib/mongoid/attributes/dynamic.rb', line 20

def respond_to?(name, include_private = false)
  super || (
    attributes &&
    attributes.has_key?(name.to_s.reader)
  )
end