2013-02-22 33 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