是否有一种简单的方法可以附加到rails中的控制器的before_action列表,以便稍后添加的其他before_action
回调将在我的回调之前而不是之后运行?
我的用处是我担心其他控制器会包含,并且我希望包含它的控制器能够添加他们自己的before_action
方法,但是在所有这些方法之后调用我的一个方法,但仍然在实际行动之前。
由于它是一群与开发人员相当大的代码库,为了实用性,我不希望这个问题的每个用户都必须prepend_before_action
或必须记住{{1我的模块在声明了它们的回调之后而不是在类的顶部。
我很确定没有内置的方法可以做到这一点,而且我对ruby中的元编程并不是很熟悉。但是,当回调正在运行时,是否有某种方法可以挂钩回调列表的内部,并在末尾添加新的回调或什么?
答案 0 :(得分:0)
我发现了一个非常简单的解决方案 - 查看ActiveSupport::Callbacks
源代码,我注意到CallbackChain#append_one
方法是将before_action回调添加到链中,每次添加时都调用remove_duplicates方法回调。所以我可以在我的模块中执行以下操作,覆盖before_action
方法:
module MyModule
extend ActiveSupport::Concern
included do
before_action :my_last_callback
end
class_methods do
def before_action(*args, &blk)
method(:before_action).super_method.call(*args, &blk)
method(:before_action).super_method.call(:my_last_callback)
end
end
def my_last_callback
# do stuff after all before_action callbacks
end
end
现在,子类可以根据需要添加尽可能多的before_action回调,并且它们将保持其顺序,但my_last_callback
始终会被调用。 (回调链中现在会有额外的插入/删除,现在回调数量可能是O(n ^ 2)而不是O(n),但我不认为有足够的回调来使这个回调问题)。