Sinatra将params 与字符串类型匹配,需要额外的转换才能匹配数据库ID?

我正在使用sinatra和DataMapper来访问sqlite3数据库。 当调用get(params[:id])时,我总是得到一个nil 。 但是当我打电话给get(params[:id].to_i)我可以得到正确的记录。 是否有任何错误,我必须明确地进行转换?

sinatra应用程序很简单:

 class Record include DataMapper::Resource property :id, Serial .... end get '/list/:id' do r = Record.get(params[:id]) ... end 

显然这是Datamapper的一个问题(如果你认为它应该将字符串转换为id的数字),但Sinatra可以通过各种方式来缓解它。 当params进来你需要检查:

  • 他们存在。
  • 他们是正确的类型(或可铸造)。
  • 它们在所需或预期的值范围内。

例如:

 get '/list/:id' do r = Record.get(params[:id].to_i) # more code… curl http://example.org/list/ddd 

这将无法正常工作,更好地检查并返回错误消息:

 get '/list/:id' do |id| # the block syntax is helpful here halt 400, "Supply an ID *number*" unless id =~ /\d+/ 

然后考虑是否需要默认值 , 值是否在正确的范围内等。当接收ID时,我倾向于使用路由的正则表达式语法 ,因为它也会停止跟随子路由被吞噬,同时提供一些简单的类型检查:

 get %r{/list/(\d+)} do |id| 

在这种情况下,助手也很有用:

 helpers do # it's not required to take an argument, # the params helper is accessible inside other helpers # it's but easier to test, and (perhaps) philosophically better. def id( ps ) if ps[:id] ps[:id].to_i else # raise an error, halt, or redirect, or whatever! end end end get '/list/:id' do r = Record.get id(params) 

澄清一下,@mbj原始问题中的评论是正确的。 这是使用Ruby 2.0的dm-core中的一个错误。 它与ruby 1.9配合得很好。 你可能在dm-core 1.2版本上需要1.2.1,你可以通过运行’gem update dm-core’来获得。