Ruby on Rails - 回调

时间:2014-07-03 01:48:46

标签: ruby-on-rails ruby callback

我的任务是为Rails应用程序(Foreman)实现一个非常基本的功能请求,并且偶然发现了一个看似非常基本且非常受欢迎的问题。来自Java背景,我发现回调不能像我通常期望的那样工作。

通常在使用侦听器的Java中,您可以为事件订阅任意代码片段,并且当事件触发时,对象会迭代侦听器并通知每个侦听器。一个非常基本的例子是:

public class Foo {
    private List<FooListener> foo_list = new List<FooListener>();
    public void add_foo_listener(FooListener fooListener){
        this.foo_list.add(fooListener);
    }
    private void on_foo_thing(){
        foreach(foo : foo_list) {
            fooListener.notify();
        }
    }
}

因此,您可以通过调用&#34; add_foo_listener(fooListener)&#34;来添加来自外部类的多个侦听器。调用on_foo_thing()方法时会通知 - 不对原始类进行任何修改。

ruby​​ / rails中有类似的东西吗?我要挂钩的类有以下定义的钩子:

define_model_callbacks :build, :only => :after
define_model_callbacks :provision, :only => :before

# Custom hooks will be executed after_commit
after_commit :build_hooks, :if => :persisted?

def build_hooks
    return unless respond_to?(:old) && old && (build? != old.build?)
    if build?
      run_callbacks :build do
        logger.debug { "custom hook after_build on #{name} will be executed if defined." }
      end
    else
      run_callbacks :provision do
        logger.debug { "custom hook before_provision on #{name} will be executed if defined." }
      end
    end
  end

1 个答案:

答案 0 :(得分:0)

虽然可能的重复是正确的,但为了更改rails中的模型而不编辑模型代码以明确包含已侦听的模型,您可以使用以下内容:

Host::Managed.send(:include, ::HostExtensions::ManagedHost)

告诉Host :: Managed类它应该在运行时包含HostExtensions :: ManagedHost模块。

为了完整起见,如果您在Rails应用程序中执行此操作,则可能需要向Engine类(engine.rb)添加类似的内容:

config.to_prepare do
  require File.expand_path('../../../app/models/concerns/host_extensions/managedhost', __FILE__)
  Host::Managed.send(:include, ::HostExtensions::ManagedHost)
end