【问题标题】:in Sinatra how do you make a "before" filter that matches all routes except some在 Sinatra 中,您如何制作一个“之前”过滤器来匹配除某些路由之外的所有路由
【发布时间】:2011-12-03 23:23:34
【问题描述】:

我有一个 Ruby Sinatra 应用程序,我有一些代码需要在所有路线上执行,除了少数例外。我该怎么做?

如果我想在选定的路线上执行代码(白名单样式),我会这样做:

['/join', "/join/*", "/payment/*"].each do |path|
    before path do
        #some code
    end
end

我该如何反其道而行之(黑名单风格)?我想匹配除'/join''/join/*''/payment/*' 之外的所有路线

【问题讨论】:

    标签: ruby sinatra


    【解决方案1】:

    负前瞻:

    before /^(?!\/(join|payment))/ do
      # ...
    end
    

    pass:

     before do
       pass if %w[join payment].include? request.path_info.split('/')[1]
       # ...
     end
    

    或者你可以创建一个custom matcher

    【讨论】:

    • 如何在这个 pass 语句中包含根路径('/')?
    • 通过 if ['join', 'payment', nil].include? request.path_info.split('/')[1]
    • 通行证对我来说效果很好,但负面的前瞻性却不行。两个问题:1)Sinatra(至少是 1.4.6)在正则表达式中有一个 ^ 字符的解析错误,2)否定的前瞻语法只检查转义的正斜杠。不允许使用可变宽度值。 rubular.com/r/HEWorY6OFU5W9S
    【解决方案2】:

    我所做的“首先,除了...”过滤器是使用 splat,然后在 splat 条件下运行代码。

    before '/*' do
      unless params[:splat] == 'nofilter' || params[:splat] == 'beta'
        redirect '/beta'
      end
    end
    

    这使我可以使用未创建重定向循环的重定向创建一个前置过滤器

    【讨论】:

      【解决方案3】:

      您可以在 sinatra 中使用正则表达式进行路由

      例如:

      get %r{/hello/([\w]+)} do |c|
         "Hello, #{c}!"
      end
      

      取自here。在那里你可以找到更多信息。

      要构建和测试您的正则表达式,您可以使用http://rubular.com/

      【讨论】:

      • 看,阅读文档已经很清楚了。文档(Sinatra:README)中不清楚的是 before filters 是否也可以采用正则表达式模式。您会注意到过滤器之前和之后在您链接到的文章的完全不同的部分中。因此,您的答案没有增加任何价值(也许最后一个链接除外),而只是重复了文档已经说明的内容。因此我投了反对票。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-26
      • 1970-01-01
      • 1970-01-01
      • 2019-04-23
      • 2017-05-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多