Skip to content

Instantly share code, notes, and snippets.

@outoftime
Created December 14, 2010 04:56
Show Gist options
  • Save outoftime/740020 to your computer and use it in GitHub Desktop.
Save outoftime/740020 to your computer and use it in GitHub Desktop.
Define single-instance lifecycle hooks for ActiveRecord 2 objects. Very useful if you want to do something after_save based on a dirty attribute observed before_save.
module InstanceLifecycleHooks
def self.included(base)
base.module_eval do
alias_method_chain :run_callbacks, :instance_lifecycle_hooks
end
end
ActiveRecord::Callbacks::CALLBACKS.each do |callback|
module_eval <<-RUBY, __FILE__, __LINE__+1
def #{callback}_instance(method = nil, &block)
@#{callback}_callback_chain ||= ActiveSupport::Callbacks::CallbackChain.new
@#{callback}_callback_chain << ActiveSupport::Callbacks::Callback.new(#{callback.to_sym.inspect}, method || block, {})
end
RUBY
end
def run_callbacks_with_instance_lifecycle_hooks(kind, options = {}, &block)
instance_variable_name = :"@#{kind}_callback_chain"
if instance_variable_defined?(instance_variable_name)
instance_chain = instance_variable_get(instance_variable_name)
begin
instance_chain.run(self, options, &block)
ensure
remove_instance_variable(instance_variable_name)
end
end
run_callbacks_without_instance_lifecycle_hooks(kind, options, &block)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment