2013-02-22 97 views
6

我在所有的类中都使用了g记录器。 我想每个MSG与类名和方法名开始像这样:在没有导轨的红宝石中实现rails before_filter

Class_name::Method_name 

这就是我现在做的:

class FOO 

def initialize 
end 

def bar 
    msg_prefix = "#{self.class}::#{__method__}" 
    ... some code ... 
    @logeer = "#{msg_prefix} msg ..." 
end 

def bar2 
    msg_prefix = "#{self.class}::#{__method__}" 
    ... some code 2 ... 
    @logeer = "#{msg_prefix} msg2 ..." 
end 

end 

我想在轨使用的before_filter像防止 我正在使用sinatra,但类是普通的ruby 1.9.3

想法??

+0

你可以使用activerecord与sinatra https://github.com/janko-m/sinatra-activerecord – AJcodez 2013-02-22 22:50:57

回答

5

你可以在任何方法的回调创建与Module#method_added别名旧方法,然后定义一个新的方法,首先调用before_filter方法。这是我的(非常)粗略的概念:

module Filter 
    def before_filter name 
    @@filter = name 
    end 

    def method_added name 
    return if @filtering # Don't add filters to original_ methods 
    return if @@filter == name # Don't filter filters 
    return if name == :initialize 

    @filtering = true 

    alias_method :"original_#{name}", name 
    define_method name do |*args| 
     self.send @@filter, name 
     self.send :"original_#{name}", *args 
    end 
    @filtering = false 
    end 
end 

class FilterTest 
    extend Filter 
    before_filter :prepare_logs 

    def baz 
    puts "#{@msg_prefix} message goes here" 
    end 

    def prepare_logs name 
    @msg_prefix = "#{self.class}::#{name}" 
    end 
end 

ft = FilterTest.new 
ft.baz 

使用__method__就像你在create_prefix,你会得到的过滤方法,而不是原来的方法的名称,所以你必须在传递方法名可能还有其他解决方案可以让它更清洁一些。

+0

感谢zaius,这的确有窍门,但我已经在超类中实现了它,它为超类本身工作,2.它是孩子,3.因为它是孙子,它给了我一个'未捕获的异常:堆栈层面太深了'我想知道为什么.. – WebQube 2013-03-01 19:27:22

+0

好吧..这是一种有趣的解决方案,所以这并不让我感到意外。将你的代码和错误信息粘贴到要点或其他东西上,然后我可以告诉你它为什么破坏。 – zaius 2013-03-01 23:01:55

+0

当然,这就是它。实例在最后。 [gist](https://gist.github.com/ohadpartuck/5070783) – WebQube 2013-03-02 12:31:55

1

您可以使用ActiveModel::Callbacks获得纯Ruby类before_filter样的行为(虽然也许在你的情况下,它是大材小用只执行一条线):

require 'active_model' 

class FOO 
    extend ActiveModel::Callbacks 

    define_model_callbacks :baz, only: :before 

    before_baz :create_prefix 

    def initialize 
    end 

    def bar 
    run_callbacks :baz do 
     ... some code ... 
     @logeer = "#{@msg_prefix} msg ..." 
    end 
    end 

    def bar2 
    run_callbacks :baz do 
     ... some code 2 ... 
     @logeer = "#{@msg_prefix} msg2 ..." 
    end 
    end 

    private 

    def create_prefix 
     @msg_prefix = "#{self.class}::#{__method__}" 
    end 
end 
+0

您好保罗,感谢您的反应,但我正在寻找一种方式来使用它的确切方式轨使用,一line''before_filter:do_prefix_msg'在每个函数之前自动运行(除非另有说明) – WebQube 2013-02-23 09:52:39

+0

我认为使用'ActiveModel :: Callbacks'是获得所需效果的最简单方法,无需重新实现相当数量的代码那就是[Rails的回调](https://github.com/rails/rails/blob/v3.2.12/actionpack/lib/abstract_controller/callbacks.rb)。前一段时间,我有一个自己的项目出现了同样的问题,找不到比“ActiveModel :: Callbacks”更好的解决方案。但是,希望别人知道别的方法,我会给这个问题+1。 – 2013-02-23 10:45:25