Skip to content

Instantly share code, notes, and snippets.

@AMHOL
Last active March 31, 2016 00:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AMHOL/d9f93dfe2ffe9ebe3c0530b18bea8c79 to your computer and use it in GitHub Desktop.
Save AMHOL/d9f93dfe2ffe9ebe3c0530b18bea8c79 to your computer and use it in GitHub Desktop.
I know, it assumes symbol attribute names only, this is for "simplicity" ~ lul
class User
def initialize(attributes = {})
update_attributes(attributes)
end
def attributes
@attributes ||= {}
end
def changes
@changes ||= {}
end
def changed?
changes.values.any? { |changeset| changeset.length > 1 }
end
def update_attributes(new_attributes)
new_attributes.each_with_object(changes) do |(attribute, new_value), changeset|
(changeset[attribute] ||= []) << new_value
end
attributes.merge!(new_attributes)
self
end
def method_missing(method, *args, &block)
if attributes.key?(method)
attributes[method]
elsif method =~ /(.*)=$/ && attributes.key?($1.to_sym)
update_attributes($1.to_sym => args.first)
elsif method =~ /(.*)_was$/ && attributes.key?($1.to_sym)
changes[$1.to_sym][-2] if changes[$1.to_sym].length > 1
else
super
end
end
def respond_to_missing?(method, _include_private = false)
if attributes.key?(method)
true
elsif method =~ /(.*)=$/ && attributes.key?($1.to_sym)
true
elsif method =~ /(.*)_was$/ && attributes.key?($1.to_sym)
true
else
super
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment