【发布时间】:2011-11-25 10:55:45
【问题描述】:
我有一些动态加载的插件,它们在启动时注册它们的路由,但是我还需要能够在它们被禁用时删除它们的路由。有没有办法删除现有的路线?
API 没有任何我能找到的方法来删除它们,我能想到的唯一其他方法就是直接访问 Sinatra::Base 中的 @routes 对象,但我不确定如果你能做到这一点,如果你能……这样做安全吗?
【问题讨论】:
我有一些动态加载的插件,它们在启动时注册它们的路由,但是我还需要能够在它们被禁用时删除它们的路由。有没有办法删除现有的路线?
API 没有任何我能找到的方法来删除它们,我能想到的唯一其他方法就是直接访问 Sinatra::Base 中的 @routes 对象,但我不确定如果你能做到这一点,如果你能……这样做安全吗?
【问题讨论】:
浏览了几分钟的代码,我没有看到任何“破坏性”改变 routes 的代码,除了:
C:\Ruby\lib\ruby\gems\1.9.1\gems\sinatra-1.3.1\lib\sinatra\base.rb:
936 def reset!
937 @conditions = []
938: @routes = {}
939 @filters = {:before => [], :after => []}
940 @errors = {}
这是一种“从轨道上核对它”的方法,可能不是您需要的。根据这项调查,我认为您需要自己修改 routes 哈希。
对于当前版本的代码,这在我看来是“安全的”,因为 route! 方法总是查找当前的路由数组并正常迭代它们(没有缓存):
def route!(base = settings, pass_block=nil)
if routes = base.routes[@request.request_method]
routes.each do |pattern, keys, conditions, block|
pass_block = process_route(pattern, keys, conditions) do |*args|
route_eval { block[*args] }
end
end
end
# Run routes defined in superclass.
if base.superclass.respond_to?(:routes)
return route!(base.superclass, pass_block)
end
route_eval(&pass_block) if pass_block
route_missing
end
在最近的版本中,围绕存储路由的 Sinatra 内部结构已经发生了变化,所以我不会在没有对每个新版本进行测试的情况下一直依赖它。更好的是,提出一个补丁,看看您是否可以将接受的功能合并到主库中。
【讨论】:
也许你会考虑这种方法,
before '/the_path_you_want_to_remove' do
redirect '/the_path_is_default_page_or_someting'
end
您可以将此before 操作用于覆盖您要删除的路由,因此该路由不会被访问和实施。
如果您想再次启用该路由,只需删除 before 操作即可。
或者删除数组 disable_routes 中的项目
before do
disable_routes = ['/test', '/test/*', '/test*']
redirect '/default_page' if disable_routes.include?(request.path_info)
end
【讨论】:
您可以通过设置 after 块来阻止路由返回任何内容。
【讨论】: