|
class TemporaryCallback |
|
def self.bind(klass, stalkers) |
|
observers = [] |
|
stalkers.each do |callback_name, stalker| |
|
# Our observer needs a name |
|
observer_class_name = "Temporary"+klass.name+callback_name.to_s.camelcase+stalker.object_id.to_s |
|
# Create a new class dynamically (it will be anonymous) |
|
anon_observer_class = Class.new(ActiveRecord::Observer) do |
|
observe klass.name.underscore.to_sym |
|
define_method(callback_name.to_sym) do |record, &block| |
|
puts "record: #{record.inspect}" |
|
if stalker.respond_to?(:call) |
|
puts "calling proc/lambda..." |
|
stalker.call(record, &block) |
|
puts "after calling proc/lambda" |
|
elsif respond_to?(stalker) |
|
send(stalker, record, &block) |
|
elsif klass.respond_to?(stalker) |
|
klass.send(stalker, record, &block) |
|
else |
|
raise "stalker must be a lambda, a proc, a parent method or a method of klass" |
|
end |
|
end |
|
end |
|
# Give a name to the anonymous class |
|
observerClass = Object.const_set(observer_class_name, anon_observer_class) |
|
# Register this new observer once it has a name |
|
observerClass.instance.instance_eval { define_callbacks(klass) } |
|
observers << observerClass |
|
end |
|
|
|
yield |
|
|
|
# Remove our Observers |
|
observers.each do |observerClass| |
|
ActiveRecord::Base.observers.disable observerClass.name.underscore.to_sym |
|
end |
|
nil |
|
end |
|
end |
|
|
|
|
|
|
|
# Example using Lambda |
|
stalker = lambda { |bike| puts "Deleted: #{bike.id}" } |
|
TemporaryCallback.bind(Bike, :after_destroy => stalker) do |
|
Bike.first.destroy |
|
end |
|
|
|
# Example using Proc |
|
stalker = Proc.new { |bike| puts "Deleted: #{bike.id}" } |
|
TemporaryCallback.bind(Bike, :after_destroy => stalker) do |
|
Bike.first.destroy |
|
end |
|
|
|
# Example using simple method |
|
def stalker(bike) |
|
puts "Deleted: #{bike.id}" |
|
end |
|
TemporaryCallback.bind(Bike, :after_destroy => :stalker) do |
|
Bike.first.destroy |
|
end |
|
|
|
|
|
# Example using active record model method |
|
class Bike < ActiveRecord::Base |
|
def self.stalker(bike) |
|
puts "Deleted: #{bike.id}" |
|
end |
|
end |
|
TemporaryCallback.bind(Bike, :after_destroy => :stalker) do |
|
Bike.first.destroy |
|
end |