2013-02-22 13 views
6

Sto usando g un logger in tutte le mie classi. Voglio ogni msg per cominciare nome della classe e nome del metodo in questo modo:implementa un rail before_filter in ruby ​​senza rail

Class_name::Method_name 

questo è quello che sto facendo ora:

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 

voglio usare un before_filter come in rotaie per impedire duplicità, Sto usando sinatra ma le classi sono semplici vecchie classi ruby 1.9.3

idee ??

+0

è possibile utilizzare activerecord con sinatra https://github.com/janko-m/sinatra-activerecord – AJcodez

risposta

5

si può ottenere una richiamata da qualsiasi metodo in fase di creazione con Module#method_added, alias il vecchio metodo, quindi definire un nuovo metodo che richiama prima il metodo before_filter. Ecco la mia (molto) di massima primo concetto:

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 

Utilizzando __method__ come se fossimo in create_prefix, si otterrà il nome del metodo del filtro, non il metodo originale, in modo da avere per passare il nome del metodo in Potrebbero esserci altre soluzioni per renderlo un po 'più pulito.

+0

grazie zaius, questo in effetti ha funzionato, ma l'ho implementato nella super classe, e ha funzionato per 1. la stessa classe super, 2. è child, 3. per i suoi nipoti, mi ha dato un'eccezione Uncaught: stack level too deep' Mi chiedo perché .. – WebQube

+0

Beh .. è una specie di soluzione hacky, quindi non mi sorprende. Incolla il tuo codice e il messaggio di errore su gist o qualcosa del genere e posso dirti perché si sta rompendo. – zaius

+0

certo, eccolo. le istanze sono alla fine. [gist] (https://gist.github.com/ohadpartuck/5070783) – WebQube

1

È possibile utilizzare ActiveModel::Callbacks per ottenere before_filter -come comportamento nelle classi di Ruby semplici (anche se forse nel tuo caso è eccessivo per solo l'esecuzione di una sola riga):

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

ciao paolo, grazie per la risposta riga 'before_filter: do_prefix_msg' da eseguire automaticamente prima di ogni funzione (a meno che non sia detto diversamente) – WebQube

+0

Penso che l'uso di' ActiveModel :: Callbacks' è il modo più semplice per ottenere l'effetto esatto desiderato senza dover reimplementare la giusta quantità di codice questo è dietro [callbacks di Rails] (https://github.com/rails/rails/blob/v3.2.12/actionpack/lib/abstract_controller/callbacks.rb). Ho avuto questo stesso problema qualche tempo fa con uno dei miei progetti e non ho trovato nessuna soluzione migliore di 'ActiveModel :: Callbacks'. Ma, nella speranza che ci sia un altro modo in cui qualcun altro lo sa, farò +1 alla domanda. –

Problemi correlati