Sinatra路由中的几个可选参数

12

我需要Sinatra路由按照以下方式运行:

GET /list/20/10  # Get 20 items with offset 10
GET /list/20     # Get 20 items with default offset
GET /list        # Get default number of items with default offset

我明白了,我可以将这些值作为查询传递:

GET /list?limit=20&offset=10

但我希望按照上述描述来传递它们。我非常确定有一种方法可以向Sinatra/Padrino解释我的意图,但我目前完全被卡住了。我已经尝试过:

get :list, :map => '/list', :with => [:limit, :offset] {} # 404 on /list
get :list, :map => '/list/*' { puts params[:splat] } # 404 on /list
get :list, :map => '/list/?:limit?/?:offset?' {} # 404 on /list
get :list, :map => '/list' { redirect url_for(:list, …) } # 302, not convenient for consumers

我应该如何提醒Sinatra参数可能是可选的?

无意中,

get %r{/list(/[^/]+)*} do
  # parse params[:captures]
end

工作了,但看起来很傻。


试试这个: https://dev59.com/qm7Xa4cB1Zd3GeqPqXsr#14885171 - Uri Agassi
@UriAgassi 这与使用 regex 进行 grep 相同,我正在寻找更清晰、更直接的方式。 - Aleksei Matiushkin
2
我认为 get "/comments/:start/?" do |start=0| 可以解决你的问题... - Uri Agassi
2个回答

23

这个最基本的例子:

#!/usr/bin/env ruby
require 'sinatra'

get '/test/?:p1?/?:p2?' do
  "Hello #{params[:p1]}, #{params[:p2]}"
end

它仅适用于/test/test/a/test/a/b。在你的问题中我有漏掉了什么吗?


哎呀...现在它对我来说像魔法一样运行良好。看起来错误是人为引起的。无论如何,还是谢谢。 - Aleksei Matiushkin
所以你需要用两个问号来包围每个可选的命名参数? - Jwan622
是的,关于可选参数的文档非常缺乏,但这就是它们的定义方式。使用问号可能是一个尴尬的决定,因为它可能会与用于查询字符串的问号混淆。 - To마SE
6
可选参数不需要两个问号。问号表示前面的字符或参数是可选的。在这种情况下,它表明斜杠是可选的,参数也是可选的。 - Jrgns
@Jrgns 你说得完全正确,文档确实需要解释一下问号的确切作用,我稍后会提交一个错误报告。 - To마SE

4

实际上,Sinatra 中的参数匹配是由 Mustermann 完成的,根据文档,您有多个匹配器可用。

Sinatra 中有:

sinatra     /:slug(.:ext)?

所以,如果你想要可选参数,你需要像上面的示例一样将它们包装在()?中,这是从文档中摘取的。

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