Я хотел использовать этот подход в своем собственном проекте, чтобы иметь возможность вводить дополнительные действия в действие «сохранить» модели из уровня моего контроллера. Я взял ответ Тадмана на шаг вперед и создал модуль, который можно внедрить в классы активной модели:
module InstanceCallbacks
extend ActiveSupport::Concern
CALLBACKS = [:before_validation, :after_validation, :before_save, :before_create, :after_create, :after_save, :after_commit]
included do
CALLBACKS.each do |callback|
class_eval <<-RUBY, __FILE__, __LINE__
#{callback} :run_#{callback}_instance_callbacks
def run_#{callback}_instance_callbacks
return unless @instance_#{callback}_callbacks
@instance_#{callback}_callbacks.each do |callback|
callback.call
end
end
def #{callback}(&callback)
@instance_#{callback}_callbacks ||= []
@instance_#{callback}_callbacks << callback
end
RUBY
end
end
end
Это позволяет вам внедрить полный набор обратных вызовов экземпляра в любую модель, просто включив модуль. В этом случае:
class Message
include InstanceCallbacks
end
И тогда вы можете делать такие вещи, как:
m = Message.new
m.after_save do
puts "In after_save callback"
end
m.save!