在ruby中调用模型中的方法之前

这是我的实现,以开发方式在模型中的所有方法之前运行代码

调用“before_hook:months_used”方法需要在类的底部到ExecutionHooks才能获得在模块中加载的instance_method.我想在顶部加载实例方法

class BalanceChart < BalanceFind
 include ExecutionHooks

 attr_reader :options

 def initialize(options = {})
  @options = options
  @begin_at = @options[:begin_at]
 end

 def months_used
  range.map{|date| I18n.l date,format: :month_year}.uniq!
 end

 before_hook :months_used
end

module ExecutionHooks

def self.included(base)
 base.send :extend,ClassMethods
end

module ClassMethods
  def before
   @hooks.each do |name|
    m = instance_method(name)
    define_method(name) do |*args,&block|  

      return if @begin_at.blank? ## the code you can execute before methods

      m.bind(self).(*args,&block) ## your old code in the method of the class
    end
   end
  end

  def before_hook(*method_name)
   @hooks = method_name
   before
  end

  def hooks
   @hooks ||= []
  end
 end
end

解决方法

您可以使用 prepend执行此操作.prepend就像包含一样,它将一个模块添加到类的祖先,但不是在它之前添加它之后添加它.

这意味着如果在前置模块和类中都存在方法,则首先调用模块实现(如果它想调用基类,它可以选择调用super).

这允许你编写一个钩子模块,如下所示:

module Hooks
  def before(*method_names)
    to_prepend = Module.new do
      method_names.each do |name| 
        define_method(name) do |*args,&block|
          puts "before #{name}"
          super(*args,&block)
        end
      end
    end
    prepend to_prepend
  end
end


class Example
  extend Hooks
  before :foo,:bar

  def foo
    puts "in foo"
  end
  def bar
    puts "in bar"
  end
end

在实际使用中,您可能希望将该模块存储在某处,以便每次调用之前都不会创建新模块,但这只是一个实现详细信息

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...