05 April 2008

Rails Prototypal Attributes

Give your models javascript-esque prototypal methods. When accessing an attribute on the prototypal object, the attribute’s value is returned if not nil. Otherwise, the “linked” object’s attribute value is returned.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# Prototypal
# Example
# =======
# 
# class Clipping
#   has_many :saved_clippings
# end
# 
# class SavedClipping
#   belongs_to :clipping
#   
#   include Prototypal
#   prototypal_attributes(:clipping, :title, :description)
# end
# 
# clipping = Clipping.new(:title => "Base Title", :description => "Base description")
# saved_clipping = SavedClipping.new(
#   :clipping => clipping, 
#   :description => "Saved clipping description"
# )
# 
# saved_clipping.title
# => "Base Title"
# 
# saved_clipping.description
# => "Saved clipping description"

module Prototypal
  def prototypal_attributes(link_name, *attribute_names)
    attribute_names.each do |attribute_name|
      
      module_eval <<-"end;"
        def #{attribute_name}
          self[:#{attribute_name}].nil? ? #{link_name}.#{attribute_name} : super
        end
      end;
      
    end
  end
end

Comments