Module: ActiveRecord::AttributeDecorators::ClassMethods

Defined in:
activerecord/lib/active_record/attribute_decorators.rb

Overview

:nodoc:

Instance Method Summary collapse

Instance Method Details

#decorate_attribute_type(column_name, decorator_name, &block) ⇒ Object

This method is an internal API used to create class macros such as serialize, and features like time zone aware attributes.

Used to wrap the type of an attribute in a new type. When the schema for a model is loaded, attributes with the same name as column_name will have their type yielded to the given block. The return value of that block will be used instead.

Subsequent calls where column_name and decorator_name are the same will override the previous decorator, not decorate twice. This can be used to create idempotent class macros like serialize



23
24
25
26
27
# File 'activerecord/lib/active_record/attribute_decorators.rb', line 23

def decorate_attribute_type(column_name, decorator_name, &block)
  matcher = ->(name, _) { name == column_name.to_s }
  key = "_#{column_name}_#{decorator_name}"
  decorate_matching_attribute_types(matcher, key, &block)
end

#decorate_matching_attribute_types(matcher, decorator_name, &block) ⇒ Object

This method is an internal API used to create higher level features like time zone aware attributes.

When the schema for a model is loaded, matcher will be called for each attribute with its name and type. If the matcher returns a truthy value, the type will then be yielded to the given block, and the return value of that block will replace the type.

Subsequent calls to this method with the same value for decorator_name will replace the previous decorator, not decorate twice. This can be used to ensure that class macros are idempotent.



40
41
42
43
44
45
46
# File 'activerecord/lib/active_record/attribute_decorators.rb', line 40

def decorate_matching_attribute_types(matcher, decorator_name, &block)
  reload_schema_from_cache
  decorator_name = decorator_name.to_s

  # Create new hashes so we don't modify parent classes
  self.attribute_type_decorations = attribute_type_decorations.merge(decorator_name => [matcher, block])
end