Module: AttributeHelpers
- Defined in:
- lib/attribute_helpers.rb,
lib/attribute_helpers/version.rb
Overview
Provides helper functionality for ruby classes that store various database-unfriendly types as instance variables. It automatically serializes and deserializes things like classes and symbols to interact easily with both the database and your application code.
Constant Summary collapse
- VERSION =
"0.1.3"
Instance Method Summary collapse
- #attr_class(*attrs) ⇒ Object
- #attr_symbol(*attrs) ⇒ Object
-
#transform_attributes(*attrs, &block) ⇒ Object
Implementation Note ——————- The transformers above all work by creating an anonymous module for each group of attributes that gets prepended into the class the AttributeHelpers module is included into.
Instance Method Details
#attr_class(*attrs) ⇒ Object
13 14 15 |
# File 'lib/attribute_helpers.rb', line 13 def attr_class(*attrs) transform_attributes(*attrs) { |val| Kernel.const_get(val) } end |
#attr_symbol(*attrs) ⇒ Object
9 10 11 |
# File 'lib/attribute_helpers.rb', line 9 def attr_symbol(*attrs) transform_attributes(*attrs, &:to_sym) end |
#transform_attributes(*attrs, &block) ⇒ Object
Implementation Note
The transformers above all work by creating an anonymous module for each group of attributes that gets prepended into the class the AttributeHelpers module is included into. These modules need to be defined at method call time to avoid leaking the overrided methods into other classes this module is included in.
This anonymous module needs to be prepended to work in ActiveRecord classes. This is because ActiveRecord doesn’t have accessors/mutators defined until an instance is created, which means we need to use the prepend pattern because attempts to use instance_method instance_method will not find the method in the class context as it will not exist until it is dynamically created when an instance is created. Prepend works for us because it inserts the behavior below the class in the inheritance hierarchy, so we can access the default ActiveRecord accessors/ mutators through the use of super().
More information here: stackoverflow.com/a/4471202/1103543
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/attribute_helpers.rb', line 36 def transform_attributes(*attrs, &block) transformer = Module.new do attrs.each do |attr| # Overwrite the accessor. define_method(attr) do val = super() val && block.call(val) end # Overwrite the mutator. define_method("#{attr}=") do |val| super(val && val.to_s) end end end prepend transformer end |