Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Define custom callbacks on ruby method

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?

like image 349
Amit Patel Avatar asked Jul 26 '26 06:07

Amit Patel


1 Answers

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)

like image 171
Thomas Avatar answered Jul 28 '26 13:07

Thomas