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.2"
Class Method Summary collapse
-
.prepended(klass) ⇒ Object
This module needs to be prepended to work in ActiveRecord classes.
Class Method Details
.prepended(klass) ⇒ Object
This 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 + super() pattern because attempts to use instance_method + binding will fail since 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
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/attribute_helpers.rb', line 19 def self.prepended(klass) # We need to store the module in a variable for use when we're in the class # context. me = self # Marks attributes as storing symbol values, providing setters and getters # for the attributes that will allow the application to use them as symbols # but store them internally as strings. # @param attrs [*Symbol] a list of the attributes that store symbols klass.define_singleton_method :attr_symbol do |*attrs| # Overwrite each attribute's methods. attrs.each do |attr| # Overwrite the accessor. me.send(:define_method, attr) do val = super() val && val.to_sym end # Overwrite the mutator. me.send(:define_method, "#{attr}=") do |val| super(val && val.to_s) end end end # Marks attributes as storing class values, providing setters and getters # for the attributes that will allow the application to use them as classes # but store them internally as strings. # @param attrs [*Symbol] a list of the attributes that store classes klass.define_singleton_method :attr_class do |*attrs| # Overwrite each attribute's methods. attrs.each do |attr| # Overwrite the accessor. # @raise [NameError] if the string can't be constantized me.send(:define_method, attr) do val = super() val && Kernel.const_get(val) end # Overwrite the mutator. me.send(:define_method, "#{attr}=") do |val| super(val && val.to_s) end end end end |