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

查看:17
本文介绍了在 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

推荐答案

您可以使用 prepend.prepend 就像 include 一样,它向类的祖先添加一个模块,但不是在类之后添加它,而是在之前添加它.

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).

这允许您像这样编写钩子模块:

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天全站免登陆