将函数添加到模块中的回调条件列表中

时间:2016-02-19 15:29:20

标签: ruby-on-rails

我有:

  • 定义了before_filter回调的控制器( UPDATE :控制器在rails应用程序中,我无法对其进行修改)
  • 一个带有一些新功能的模块,添加到控制器中( UPDATE :模块在我的插件中)

我希望这个回调在这些函数之前执行。

<input data-bind="kendoAutoComplete:
{
    value: value,
    data: suggestions,
    filtering: onSuggestionsChanged
}" />

如果我这样做,列表将被重新定义,并且在“show”之前不会调用“prepare”。

我看到的选项:

class MyController < ApplicationController
  before_filter :prepare, :only => :show

  def show
  end

  def edit
  end

  private

  def prepare
  end
end 

module MyModule  
  def self.included(base)
    base.send(:include, InstanceMethods)
    base.before_filter :prepare, :only => [:a, :b]
  end

  module InstanceMethods
    def a
      ...
    end
    def b
      ...
    end
  end
end

  def self.included(base)
    base.send(:include, InstanceMethods)
    base.before_filter :prepare, :only => [:a, :b, :show]
  end

    def a
      prepare
      ...
    end
    def b
      prepare
      ...
    end

非常难看且没有干。

有没有自然的方法呢?

2 个答案:

答案 0 :(得分:0)

也许你应该

before_filter :prepare, :except => [:foo, :bar, :etc]

我认为我会选择:a:b

顺便说一句,你的控制器看起来可能很胖。也许,重构的机会?

答案 1 :(得分:0)

也许你正在寻找这样的东西:

module MyModule  
  def self.included(base)
    base.send(:include, InstanceMethods)
    base.extend ClassMethods
  end

  module ClassMethods
    def prepare(*actions)
      # optional - add defaults
      actions = ([:a, :b] + (actions || [])).uniq
      # self here is the singelton class object
      self.instance_eval do
        before_filter :prep, only: actions
      end
    end
  end

  module InstanceMethods
    def prep
      prepare
    end
    ...
  end
end 

我们创建一个prepare类方法,该方法采用splat,然后使用与默认值合并的动作的splat来评估before_filter。

class ThingsController < ApplicationController
  include MyModule
  prepare :show
end