2016-04-21 9 views
2

Ich habe viele Service-Klassen mit call Methode mit Variation in Argumenten.Definieren Sie benutzerdefinierte Rückrufe auf Ruby-Methode

Ich möchte eine Funktion notify am Ende jeder call Methode aufrufen. Ich möchte diese Serviceklassen nicht ändern, aber ich bin offen für die Änderung der Basisklasse.

Ich spiele mit ActiveSupport::Callbacks, aber es dient nicht dem Zweck, Serviceklasse nicht zu ändern.

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 Um Rückrufe zu laufen, muss ich den kommentierten Code Kommentar-. Aber hier können Sie sehen, dass ich vorhandene Klassen ändern muss, um run_callbacks Block hinzuzufügen. Aber das ist nicht was ich will. Ich kann einfach die Methode notify aufrufen, ohne eine solche Komplexität hinzuzufügen.

Kann jemand vorschlagen, wie kann ich die Lösung Rubin Weg?

Antwort

3

Ich würde so etwas tun:

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 

Eine andere Lösung ohne Active:

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 

Sie sollten Ihre Ruby-Version prepend überprüfen, ist eine "neue" Methode (2.0)

+0

Sieht aus Gut, aber wieder dient es nicht dem Zweck. Ich möchte nicht alle Kinderklassen ändern. Außerdem würde die vorgeschlagene Lösung alle Verweise auf die Aufrufmethode ändern müssen. –

+1

So wird ActiveSupport :: Callbacks in Rails verwendet ... Sie können auch ein Notifier-Modul voranstellen (siehe bearbeitete Antwort) – ThomasSevestre

+0

Awsome. Ich liebe zweite Lösung. Vielen Dank –