【问题标题】:How do you remove a route from Sinatra?如何从 Sinatra 中删除路线?
【发布时间】:2011-11-25 10:55:45
【问题描述】:

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

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

【问题讨论】:

    标签: ruby routing sinatra


    【解决方案1】:

    浏览了几分钟的代码,我没有看到任何“破坏性”改变 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 内部结构已经发生了变化,所以我不会在没有对每个新版本进行测试的情况下一直依赖它。更好的是,提出一个补丁,看看您是否可以将接受的功能合并到主库中。

    【讨论】:

    • 有点愚蠢的问题,但是您如何在 github 上提出补丁?您是否提出问题并仅详细说明您想要的功能,还是我应该分叉,自己添加功能,然后以某种方式通知他们我已经进行了更改?如果这是一个冗长的答案,那就这么说吧,我会去网上在 github 上查找一些信息,因为我没有用过那么多。
    • 你可以从一个问题开始。通常更容易分叉 Sinatra,进行自己的更改(确保您有测试用例和文档),将它们推送回您的 GitHub 分支,然后使用 GitHub 的“拉取请求”功能请求他们合并您的更改。阅读更多here
    • 谢谢,我回家再详细看看
    【解决方案2】:

    也许你会考虑这种方法,

    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
    

    【讨论】:

    • 这是可能的,但我想删除它们的原因是因为我有一个插件样式系统,所以如果一个插件被卸载,我想从系统中完全删除路由。不过你是对的,这是解决问题的方法。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2020-07-14
      • 1970-01-01
      • 1970-01-01
      • 2018-08-25
      • 1970-01-01
      • 2016-06-04
      • 2014-09-25
      • 2022-12-05
      • 2012-05-03
      相关资源
      最近更新 更多