2013-02-22 33 views
6

Tôi đang sử dụng g một logger trong tất cả các lớp học của tôi. Tôi muốn mỗi msg để bắt đầu với tên lớp và tên phương pháp như vậy:thực hiện một đường ray before_filter trong ruby ​​mà không có đường ray

Class_name::Method_name 

đây là những gì tôi đang làm bây giờ:

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 

tôi muốn sử dụng một before_filter như trong đường ray để ngăn chặn trùng lặp, Tôi đang sử dụng sinatra nhưng các lớp học là đồng bằng cũ ruby 1.9.3 lớp học

ý tưởng ??

+0

bạn có thể sử dụng activerecord với sinatra https://github.com/janko-m/sinatra-activerecord – AJcodez

Trả lời

5

Bạn có thể nhận được một cuộc gọi lại vào phương pháp nào được tạo ra với Module#method_added, bí danh phương thức cũ, sau đó xác định phương thức mới gọi trước phương thức before_filter. Dưới đây là (vô cùng) thô khái niệm đầu tiên của tôi:

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 

Bằng cách sử dụng __method__ như bạn đang ở trong create_prefix, bạn sẽ nhận được tên của phương pháp lọc, không phải là phương pháp ban đầu, vì vậy bạn phải vượt qua các tên phương pháp trong Có thể có các giải pháp khác để làm sạch hơn một chút.

+0

cảm ơn zaius, điều này thực sự đã làm các trick, nhưng tôi đã thực hiện nó trong lớp siêu, và nó đã làm việc cho 1. siêu lớp chính nó, 2. đó là con, 3. cho nó grandsons, nó đã cho tôi một ngoại lệ Uncaught: stack level too deep' Tôi tự hỏi tại sao .. – WebQube

+0

Vâng .. đó là một loại giải pháp hacky, vì vậy mà không làm tôi ngạc nhiên. Dán mã của bạn và thông báo lỗi lên trên gist hoặc một cái gì đó và tôi có thể cho bạn biết lý do tại sao nó phá vỡ. – zaius

+0

chắc chắn, đây là nó. các trường hợp ở cuối. [gist] (https://gist.github.com/ohadpartuck/5070783) – WebQube

1

Bạn có thể sử dụng ActiveModel::Callbacks để có được before_filter -like hành vi trong lớp học của Ruby đồng bằng (mặc dù có lẽ trong trường hợp của bạn đó là quá mức cần thiết với giá chỉ thực hiện một dòng):

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

hi paul, cảm ơn phản hồi, nhưng tôi đang tìm cách sử dụng nó theo cách chính xác của đường ray, một line 'before_filter: do_prefix_msg' chạy tự động trước mỗi chức năng (trừ khi được nói khác) – WebQube

+0

Tôi nghĩ rằng việc sử dụng' ActiveModel :: Callbacks' là cách dễ nhất để có được hiệu ứng chính xác mà bạn muốn mà không phải thực hiện lại số lượng mã đằng sau các cuộc gọi lại của [Rails] (https://github.com/rails/rails/blob/v3.2.12/actionpack/lib/abstract_controller/callbacks.rb). Tôi đã có vấn đề tương tự này trong khi trước đây với một trong các dự án của riêng tôi, và không thể tìm thấy bất kỳ giải pháp tốt hơn so với 'ActiveModel :: Callbacks'. Nhưng, với hy vọng rằng có một số cách khác mà người khác biết, tôi sẽ +1 câu hỏi. –

Các vấn đề liên quan