Skip to content

Instantly share code, notes, and snippets.

@jacqui
Created February 25, 2009 14:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jacqui/70186 to your computer and use it in GitHub Desktop.
Save jacqui/70186 to your computer and use it in GitHub Desktop.
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)
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment