Reputation: 15985
I have many service classes with call
method having variation in arguments.
I want to call a function notify
at the end of each call
method. I don't want to modify those service classes but I am open to modify base class.
I am playing with ActiveSupport::Callbacks
but it doesn't serve the purpose of not modifying service class.
require 'active_support'
class Base
include ActiveSupport::Callbacks
define_callbacks :notifier
set_callback :notifier, :after do |object|
notify()
end
def notify
puts "notified successfully"
end
end
class NewPost < Base
def call
puts "Creating new post on WordPress"
# run_callbacks :notifier do
# puts "notifying....."
# end
end
end
class EditPost < Base
def call
puts "Editing the post on WordPress"
# run_callbacks :notifier do
# puts "notified successfully"
# end
end
end
person = NewPost.new
person.call
Problem In order to run callbacks, I need to uncomment the commented code. But here you can see that I need to modify existing classes to add run_callbacks
block. But that is not what I want. I can easily call notify
method instead without adding such complexity.
Can anybody suggest how can I get to the solution ruby way?
Upvotes: 3
Views: 4859
Reputation: 1113
Generally the callbacks are set in the inheriting classes. Not sure what you want to achieve from your example, but from your initial description it should be this:
require 'active_support'
class Base
include ActiveSupport::Callbacks
define_callbacks :call
def call
run_callbacks(:call) { puts "something is happening..." }
end
end
class Post < Base
set_callback :notify, :after, :call
private
def notify
puts "new post!"
end
end
post = Post.new
post.call
Upvotes: 0
Reputation: 1633
I would do something like this:
require 'active_support'
class Base
include ActiveSupport::Callbacks
define_callbacks :notifier
set_callback :notifier, :after do |object|
notify()
end
def notify
puts "notified successfully"
end
def call
run_callbacks :notifier do
do_call
end
end
def do_call
raise 'this should be implemented in children classes'
end
end
class NewPost < Base
def do_call
puts "Creating new post on WordPress"
end
end
person = NewPost.new
person.call
Another solution without ActiveSupport:
module Notifier
def call
super
puts "notified successfully"
end
end
class NewPost
prepend Notifier
def call
puts "Creating new post on WordPress"
end
end
NewPost.new.call
You should check your ruby version prepend
is a "new" method (2.0)
Upvotes: 5