2013-02-22 18 views
6

Tüm sınıflarımda bir logger kullanıyorum.raylar olmadan rub içinde before_filter bir ray uygulamak

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 

i önlemek için rayların olduğu gibi bir before_filter kullanmak istiyorum: Bu ben şimdi ne yapıyorum

Class_name::Method_name 

: Her msg şöyle sınıf adı ve yöntem adı ile başlamak istiyorum duplicity, sinatra kullanıyorum ama sınıflar düz ruby 1.9.3 sınıfları

fikirleri ??

(belki sizin durumda sadece bir satır yürütmek için overkill rağmen) Düz Yakut sınıflarında before_filter benzeri davranışı elde etmek ActiveModel::Callbacks kullanabilirsiniz
+0

sinatra ile kullanabilirsiniz https://github.com/janko-m/sinatra-activerecord – AJcodez

cevap

5

herhangi yönteme bir geri arama alabilirsiniz Module#method_added ile, eski yöntemi takma, sonra önce before_filter yöntemini çağıran yeni bir yöntem tanımlar. İçinde yöntem adı geçmek zorunda böylece, filtre yöntemi değil orijinal yöntem adını alırsınız, sen create_prefix vardı gibi __method__ kullanarak

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 

: İşte benim (aşırı) kaba ilk konsept Bunu biraz daha temiz hale getirmek için başka çözümler de olabilir.

+0

teşekkürler zaius, bu gerçekten hile yaptı, ama süper sınıfında uyguladık ve 1. süper sınıfın kendisi için çalıştı, 2. bu çocuk, 3. torunları için, bana bir “Yakalanma istisnası verdi: yığın seviyesi çok derin 'Neden acaba .. – WebQube

+0

Şey .. Bu hacky bir çözüm, bu beni şaşırtmadı. Kodunuzu ve hata mesajını gist veya bir şey üzerine yapıştırın ve neden kırıldığını anlatabilirim. – zaius

+0

emin, işte burada. Örnekler sonunda. [g] (https://gist.github.com/ohadpartuck/5070783) – WebQube

1

: yaratılıyor

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

merhaba paul, cevap için teşekkürler, ama rayları kullanmak için tam olarak kullanmak için bir yol arıyorum, bir before_filter çizgi ': (farklı anlattı sürece) do_prefix_msg' ben ActiveModel :: Callbacks' kod adil miktarda yeniden uygulamaya gerek kalmadan tam olarak istediğiniz etkiyi elde etmek kolay yoludur' kullanarak düşünüyorum – WebQube

+0

her işlev önce otomatik olarak çalıştırmak için [Rails 'geri aramalarının arkasında] var (https://github.com/rails/rails/blob/v3.2.12/actionpack/lib/abstract_controller/callbacks.rb). Aynı projeyi kendi projelerimden birinde bir süre önce yaşadım ve 'ActiveModel :: Callbacks'den daha iyi bir çözüm bulamadım. Fakat, umarız ki, başka birinin bildiği başka bir yol var, soruyu + 1'leyeceğim. –

İlgili konular