在Ruby上的模型中的方法之前调用 [英] call before methods in model on ruby

查看:97
本文介绍了在Ruby上的模型中的方法之前调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

This my implementation to developing way to run code before all method in your model

调用"before_hook:months_used"方法必须位于ExecutionHooks的类的底部,这样才能将instance_method加载到模块中.我想将实例方法加载到顶部

The call "before_hook :months_used" method need to be on bottom of class to the ExecutionHooks can get the instance_method loaded in the module. I would like to load the instance methods on top

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

推荐答案

您可以使用

You can do this with prepend. prepend is like include in that it adds a module to the ancestors of the class, however instead of adding it after the class it adds it before.

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

This means that if a method exists both in the prepended module and the class then the module implementation is called first (and it can optionally call super if it wants to call the base class).

这使您可以像这样编写一个hooks模块:

This allows you to write a hooks module like so:

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

在实际使用中,您可能希望将该模块存储在某个地方,以便每次调用before都不会创建新模块,但这仅仅是一个填充细节

In real use you would probably want to stash that module somewhere so that each call to before doesn't create a new module but that is just an inplementation detail

这篇关于在Ruby上的模型中的方法之前调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆