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.



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

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.



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

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



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

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.



42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/dynamic_attributes.rb', line 42

def evaluate_dynamic_attributes
  new_dynamic_attributes = {}
  self.persisting_dynamic_attributes.uniq.each do |dynamic_attribute| 
    value = send(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:

  • (Boolean)


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

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.



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

def persisting_dynamic_attributes
  @persisting_dynamic_attributes ||= []
end

#populate_dynamic_attributesObject

After find, populate the dynamic attributes and create accessors



57
58
59
# File 'lib/dynamic_attributes.rb', line 57

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

#update_attributes(attributes) ⇒ Object

Overrides update_attributes to take dynamic attributes into account



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

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