2013-02-22 58 views
6

मैं अपने सभी वर्गों में जी लॉगर का उपयोग कर रहा हूं।रेल के बिना रूबी में पहले_फिल्टर को लागू करें

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 का उपयोग करने से रोकने के लिए चाहते हैं:

Class_name::Method_name 

इस अब मैं क्या कर रहा है: मैं हर संदेश इसलिए की तरह वर्ग के नाम और विधि नाम के साथ शुरू करना चाहते हैं डुप्लिकेट, मैं sinatra का उपयोग कर रहा हूं लेकिन कक्षाएं पुरानी हैं ruby 1.9.3 कक्षा

विचार ??

+0

आप sinatra के साथ activerecord का उपयोग कर सकते हैं https://github.com/janko-m/sinatra-activerecord – AJcodez

उत्तर

5

आप किसी भी विधि पर एक कॉलबैक प्राप्त कर सकते हैं बनाया जा रहा Module#method_added के साथ, पुरानी विधि उपनाम, फिर एक नई विधि को परिभाषित करें जो पहले_फिल्टर विधि को पहले कॉल करे। यहाँ मेरी (अत्यंत) किसी न किसी तरह पहली अवधारणा है:

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

धन्यवाद जैयस, यह वास्तव में चाल है, लेकिन मैंने इसे सुपर क्लास में कार्यान्वित किया है, और यह सुपर क्लास के लिए काम करता है, 2. यह बच्चा है, 3. इसके पोते के लिए, उसने मुझे 'अपवाद अपवाद दिया: ढेर स्तर बहुत गहरा 'मुझे आश्चर्य है कि क्यों .. – WebQube

+0

अच्छा .. यह एक हैकी समाधान है, जिससे मुझे आश्चर्य नहीं होता है। अपने कोड और त्रुटि संदेश को गस्ट या कुछ पर चिपकाएं और मैं आपको बता सकता हूं कि यह क्यों टूट रहा है। – zaius

+0

यकीन है, यह है। उदाहरण अंत में हैं। [gist] (https://gist.github.com/ohadpartuck/5070783) – WebQube

1

आप ActiveModel::Callbacks का उपयोग सादे रूबी कक्षाओं में before_filter की तरह व्यवहार प्राप्त करने के लिए कर सकते हैं (हालांकि शायद आपके मामले में यह सिर्फ एक पंक्ति को क्रियान्वित करने के लिए overkill है):

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

हाय पॉल, प्रतिक्रिया के लिए धन्यवाद, लेकिन मैं रेलवे का उपयोग करने के लिए सही तरीके से इसका उपयोग करने का एक तरीका ढूंढ रहा हूं, एक लाइन 'first_filter: do_prefix_msg' प्रत्येक फ़ंक्शन से पहले स्वचालित रूप से चलाने के लिए (0 अलग-अलग बताए जाने तक) – WebQube

+0

मुझे लगता है कि' ActiveModel :: Callbacks' का उपयोग करना सटीक प्रभाव प्राप्त करने का सबसे आसान तरीका है जिसे आप उचित मात्रा में कोड को दोबारा लागू नहीं करना चाहते हैं यह पीछे है [रेल के कॉलबैक] (https://github.com/rails/rails/blob/v3.2.12/actionpack/lib/abstract_controller/callbacks.rb)। मेरे पास अपनी पहली परियोजनाओं में से एक के साथ कुछ ही समय पहले ही यही समस्या थी, और 'ActiveModel :: Callbacks' से बेहतर समाधान नहीं मिला। लेकिन, उम्मीद है कि कोई अन्य तरीका है कि कोई और जानता है, मैं सवाल +1 कर दूंगा। –