我希望在 Ruby on Rails 2.3.2 中有一种更动态的方式来处理过滤器链。
目前,过滤器链是在加载类时构建的。我非常需要在加载类后的某个时间点重建过滤器链。
这与使用扩展的 Rails 项目(我猜是 Spree,Radiant 也可能受到影响)有关,该扩展可以在为 MyController 构建过滤器链后执行以下操作:
MyController.class_eval do
before_filter :my_filter_method
end
ApplicationController.class_eval do
before_filter :app_filter_method
end
这里的问题是app_filter_method
过滤器不会被添加到 MyController 过滤器链中。这是因为 MyController 的过滤器链是从 ApplicationController 的过滤器链的早期副本构建的。ApplicationController 的过滤器链的这个副本还没有应用app_filter_method
过滤器。
到目前为止,我能想到 2 个地方可能会发生 FilterChain 的重建:
1) 每次在 MyController.filter_chain 上调用它
2) 可按需重新加载。所以 MyController.reload_filter_chain 将重建过滤器链,使用来自链中 MyController 子类的过滤器。
也许指定一个 FilterChain 的子类,例如为每个请求构建过滤器链的 ReloadableFilterChain 可能会这样做 - 想法?
以下是 GitHub 上用于 Ruby on Rails 2.3.2 的 filters.rb 源的链接:
我希望你们中的一些人可能对如何做到这一点有一些见解或建议。
非常感谢任何帮助。
艾略特
根据要求提供更多详细信息:
Spree 是一个使用扩展来修改行为的 Rails 应用程序。
有时扩展用于向控制器添加过滤器(例如在问题中的示例代码中)。一个示例使用是静态内容扩展。
静态内容扩展允许您显示存储在数据库中的 HTML 页面,以针对您指定的任何请求路径显示。例如,您可以显示这些 HTML 页面之一,而不是 Spree 为 /products 请求路径显示的默认内容。
静态内容扩展过滤所有请求并检查路径。如果路径与 db 中的某个页面匹配,则过滤器会呈现该页面。
静态内容扩展声明其过滤器,如下所示:
Spree::BaseController.class_eval do
before_filter :render_page_if_exists
def render_page_if_exists
...
end
end