Module: DynamicAttributes

Defined in:
lib/dynamic_attributes.rb

Overview

The DynamicAttributes module handles all dynamic attributes.

Class Method Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *arguments, &block) ⇒ Object

Creates an accessor when a non-existing setter with the configured dynamic attribute prefix is detected. Calls super otherwise.



78
79
80
# File 'lib/dynamic_attributes.rb', line 78

def method_missing(method, *arguments, &block) 
  (method.to_s =~ /#{self.dynamic_attribute_prefix}(.+)=/) ? set_dynamic_attribute(self.dynamic_attribute_prefix + $1, *arguments.first) : super
end

Class Method Details

.included(object) ⇒ Object

Ensures the configured dynamic attribute field is serialized by AR.



90
91
92
93
94
95
# File 'lib/dynamic_attributes.rb', line 90

def self.included object
  super
  object.after_find  :populate_dynamic_attributes         
  object.before_save :evaluate_dynamic_attributes    
  object.serialize object.dynamic_attribute_field
end

Instance Method Details

#after_findObject

Explicitly define after_find for Rails 2.x



69
# File 'lib/dynamic_attributes.rb', line 69

def after_find; populate_dynamic_attributes end

#evaluate_dynamic_attributesObject

On saving an AR record, the attributes to be persisted are re-evaluated and written to the serialization field.



49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/dynamic_attributes.rb', line 49

def evaluate_dynamic_attributes
  new_dynamic_attributes = {}
  self.persisting_dynamic_attributes.uniq.each do |dynamic_attribute| 
    value = read_dynamic_attribute(dynamic_attribute)
    if value.nil? and destroy_dynamic_attribute_for_nil
      self.persisting_dynamic_attributes.delete(dynamic_attribute)
      singleton_class.send(:remove_method, dynamic_attribute + '=')
    else
      new_dynamic_attributes[dynamic_attribute] = value
    end
  end
  write_attribute(self.dynamic_attribute_field, new_dynamic_attributes)
end

#has_dynamic_attribute?(dynamic_attribute) ⇒ Boolean

Returns whether a given attribute is a dynamic attribute

Returns:

  • (Boolean)


38
39
40
# File 'lib/dynamic_attributes.rb', line 38

def has_dynamic_attribute?(dynamic_attribute)
  return persisting_dynamic_attributes.include?(dynamic_attribute.to_s)
end

#initialize(attributes = nil) ⇒ Object

Overrides the initializer to take dynamic attributes into account



30
31
32
33
34
35
# File 'lib/dynamic_attributes.rb', line 30

def initialize(attributes = nil)
  dynamic_attributes = {}
  (attributes ||= {}).each{|att,value| dynamic_attributes[att] = value if att.to_s.starts_with?(self.dynamic_attribute_prefix) }
  super(attributes.except(*dynamic_attributes.keys))   
  set_dynamic_attributes(dynamic_attributes)    
end

#persisting_dynamic_attributesObject

Returns the dynamic attributes that will be persisted to the serialization column. This array can be altered to force dynamic attributes to not be saved in the database or to persist other attributes, but it is recommended to not change it at all.



85
86
87
# File 'lib/dynamic_attributes.rb', line 85

def persisting_dynamic_attributes
  @persisting_dynamic_attributes ||= []
end

#populate_dynamic_attributesObject

After find, populate the dynamic attributes and create accessors



64
65
66
# File 'lib/dynamic_attributes.rb', line 64

def populate_dynamic_attributes
  (read_attribute(self.dynamic_attribute_field) || {}).each {|att, value| set_dynamic_attribute(att, value); self.destroy_dynamic_attribute_for_nil = false if value.nil? }
end

#read_dynamic_attribute(dynamic_attribute) ⇒ Object

Reads the value of the given dynamic attribute. Returns nil if the attribute does not exist or if it is not a dynamic attribute.



44
45
46
# File 'lib/dynamic_attributes.rb', line 44

def read_dynamic_attribute(dynamic_attribute)
  has_dynamic_attribute?(dynamic_attribute) ? (send(dynamic_attribute) rescue nil) : nil
end

#singleton_classObject

Gets the object’s singleton class. Backported from Rails 2.3.8 to support older versions of Rails.



98
99
100
101
102
# File 'lib/dynamic_attributes.rb', line 98

def singleton_class
  class << self
    self
  end
end

#update_attributes(attributes) ⇒ Object

Overrides update_attributes to take dynamic attributes into account



72
73
74
75
# File 'lib/dynamic_attributes.rb', line 72

def update_attributes(attributes)  
  set_dynamic_attributes(attributes)  
  super(attributes)
end