implement a rails before_filter in ruby without rails

六眼飞鱼酱① 提交于 2019-12-05 21:18:13

问题


I am using g a logger in all of my classes. I want each msg to begin with class name and method name like so:

Class_name::Method_name

this is what i'm doing now :

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 want to use a before_filter like in rails to prevent duplicity, I am using sinatra but the classes are plain old ruby 1.9.3 classes

ideas??


回答1:


You can get a callback on any method being created with Module#method_added, alias the old method, then define a new method that calls the before_filter method first. Here's my (extremely) rough first concept:

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

By using __method__ like you were in create_prefix, you'll get the name of the filter method, not the original method, so you have to pass the method name in. There might be other solutions to make that a bit cleaner.




回答2:


You can use ActiveModel::Callbacks to get before_filter-like behaviour in plain Ruby classes (though perhaps in your case it's overkill for just executing one line):

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


来源:https://stackoverflow.com/questions/15034125/implement-a-rails-before-filter-in-ruby-without-rails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!