如何从 Sinatra 中删除路线?

发布于 2024-12-17 09:05:45 字数 179 浏览 2 评论 0原文

我有一些动态加载的插件,它们在启动时注册它们的路由,但是我还需要能够在禁用它们时删除它们的路由。有没有办法删除现有的路线?

API 没有任何我能找到的方法来删除它们,我能想到的唯一其他方法就是直接访问 Sinatra::Base 中的 @routes 对象,但我不确定你是否可以对此采取任何措施,如果可以的话……这样做安全吗?

I have some dynamically loaded plugins which register their routes when they start up, however I also need to be able to remove their routes when they are disabled. Is there a way to remove existing routes?

The API didn't have any methods I could find to remove them, and the only other way I could think to do it would be to go right to the @routes object in Sinatra::Base, but I am not sure if you can do anything to that, and if you can... is it safe to do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

勿忘初心 2024-12-24 09:05:45

浏览代码几分钟,我没有看到任何“破坏性”改变路线的代码,除了:

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 存储路由的内部结构最近发生了变化版本,所以我不会依赖它总是在不测试每个新版本的情况下工作。更好的是,提出一个补丁,看看是否可以将接受的功能合并到主库中。

Looking through the code for a few minutes I do not see any code that 'destructively' mutates the routes other than:

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         = {}

This is a 'nuke it from orbit' approach, and presumably not what you need. Based on this investigation, I think you will need to modify the routes hash yourself.

For the current version of code, this looks 'safe' to me, insofar as the route! method always looks up the current array of routes and iterates them normally (there is no caching):

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

The internals of Sinatra around storing routes have shifted in recent releases, so I wouldn't rely on this always working without testing with each new release. Better yet, propose a patch and see if you can get the functionality accepted incorporated into the main library.

﹂绝世的画 2024-12-24 09:05:45

也许您考虑这种方法,

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

May be you condider this approach,

before '/the_path_you_want_to_remove' do
   redirect '/the_path_is_default_page_or_someting'
end

You could put this before action for overriding the route you want to remove, so the route is not be accessed and implemented.

If you want to enable that route again, just delete the before action.

Or remove the item in array disable_routes

before do
    disable_routes = ['/test', '/test/*', '/test*']
    redirect '/default_page' if disable_routes.include?(request.path_info)
end
如果没结果 2024-12-24 09:05:45

您可以通过设置 after 块来阻止路由返回任何内容。

You could prevent the route from returning anything by setting an after block.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文