jacqui (owner)

Forks

Revisions

gist: 70186 Download_button fork
public
Public Clone URL: git://gist.github.com/70186.git
Embed All Files: show embed
delegate_attributes.rb #
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
module DelegateAttributes
 
  def self.included(base)
    base.class_eval do
      extend ClassMethods
    end
  end
 
  module ClassMethods
    def delegate_or_override(*methods)
      options = methods.pop
      unless options.is_a?(Hash) && to = options[:to]
        raise ArgumentError, "Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate_or_override :hello, :to => :greeter)."
      end
 
      methods.each do |method|
        method_str = ""
        source_method, dest_method = *method
        dest_method ||= source_method
 
        method_str =<<-END_DEF
def #{source_method}(*args, &block)
if read_attribute(:#{source_method})
read_attribute(:#{source_method})
elsif #{to}
#{to}.__send__(#{dest_method.inspect}, *args, &block)
end
end
END_DEF
        file, line = caller[0].split(/:/)
        module_eval(method_str, file, line.to_i)
      end
    end
  end
end
 
ActiveRecord::Base.send(:include, DelegateAttributes)
example_model.rb #
1
2
3
4
5
class ExampleModel < ActiveRecord::Base
  # give it an array of attribute names just like delegate
  # when the attributes do not have the same name, pass an array [:source_attr, :associated_attr]
  delegate_or_override :contact_name, :contact_email, [:contact_phone, :phone_number], [:contact_website, :website], :to => :client
end