在Sinatra中,如何创建一个“before”过滤器,匹配除某些路由之外的所有路由?

35
我有一个Ruby Sinatra应用程序,有些代码需要在除了几个例外之外的所有路由上执行。我该怎么做?
如果我想在选择的路由上执行代码(白名单样式),我会这样做:
['/join', "/join/*", "/payment/*"].each do |path|
    before path do
        #some code
    end
end

但如何实现反向操作(黑名单方式)呢?我想匹配除了'/join''/join/*''/payment/*'之外的所有路由。

3个回答

44

使用负向前瞻:

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

使用 pass

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

或者你可以创建一个自定义匹配器


我该如何在这个pass语句中包含根路径('/')? - Marcio Toshio
1
if ['join', 'payment', nil].include? request.path_info.split('/')[1] pass end - Konstantin Haase
这个正则表达式对我来说很好用,但是负向先行断言不行。有两个问题:1)Sinatra(至少1.4.6版本)在正则表达式中使用^字符时会出现解析错误;2)负向先行断言语法只检查转义的斜杠。不允许使用可变宽度值。https://rubular.com/r/HEWorY6OFU5W9S - mrturtle

4
我是一名有帮助的助手,为您翻译如下内容:使用展开运算符“splat”可实现“除...之外全部”的筛选条件,并在此基础上执行相应代码。
before '/*' do
  unless params[:splat] == 'nofilter' || params[:splat] == 'beta'
    redirect '/beta'
  end
end

这使得我可以使用重定向创建一个before过滤器,而不会形成重定向循环。

1

你可以在Sinatra中使用正则表达式进行路由匹配

例如:

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

这里获取。在那里你可以找到更多信息。

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


看,从阅读文档中已经很清楚了。从文档(Sinatra: README)中不清楚的是before filters是否也可以采用正则表达式模式。你会注意到before and after filters在你链接的文章中完全不同的部分。因此,你的回答没有增加任何价值(除了最后一个链接),只是重复了文档中已经说明的内容。因此我给你的回答点了个踩。 - 0xC0000022L

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接