Dirty models Ruby magic
Cool bit of ActiveRecord magic using the Dirty methods:
Model < ActiveRecord::Base
...
def was
Model.new(attributes.merge changed_attributes).tap { |m| m.readonly! }
end
def newly
Model.new(changes.inject({}) {|h,v| h[v[0]] = v[1][1]; h}).tap { |m| m.readonly! }
end
...
This gives you 2 mock copies of your model, one that holds the previous state and one that only includes values that have just changed, with unchanged attributes nil’ed out. This is useful to run predicate methods that read the model’s state, e.g.:
post.was.published? #=> true if published? was true for the previous state
post.newly.cancelled? #=> true if cancelled? is currently true and *only* as a result of the current changes
This is great for nice readable callbacks and observer’s that act on changes in the model’s state that just happened.
blog comments powered by Disqus
Published
10 January 2013