Skip to content

Instantly share code, notes, and snippets.

@samuelkadolph
Created December 29, 2010 23:08
Show Gist options
  • Save samuelkadolph/759193 to your computer and use it in GitHub Desktop.
Save samuelkadolph/759193 to your computer and use it in GitHub Desktop.
How to safely add a class method to your models that affects attributes
class ApplicationModel < ActiveRecord::Base
self.abstract_class = true
class_attribute :formatted_attributes_options
self.formatted_attributes_options = {}
def self.formatted_attributes(*attributes)
options = attributes.extract_options!
attributes.each do |attribute|
formatted_attributes_options[attribute] = options
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
remove_method(:#{attribute}) if method_defined?(:#{attribute})
def #{attribute}(format = nil)
format_attribute(:#{attribute}, format)
end
RUBY_EVAL
end
end
def format_attribute(attribute, format = nil)
value = read_attribute(attribute)
return value if format.nil?
formatter = formatted_attributes_options[attribute][format]
raise(ArgumentError.new("#{format} is not a format for #{attribute}")) unless formatter
formatter.respond_to?(:call) ? formatter.call(value) : formatter % value
end
end
class Gizmo < ApplicationModel
formatted_attributes :price, :short => lamda { |price| ("%.2f" % price).gsub('.00', '.--').gsub('.', ',') }, :nice => ""
end
@ionas
Copy link

ionas commented Dec 29, 2010

Thanks, I hope I understand more and more of the call flow later :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment