Sinatra将params [:id]与字符串类型匹配,需要额外的转换来匹配数据库ID吗?

时间:2013-04-30 15:56:02

标签: ruby sinatra datamapper

我正在使用sinatra和DataMapper来访问sqlite3数据库。在致电nil时,我总是得到get(params[:id])。但是当我打电话给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

2 个答案:

答案 0 :(得分:2)

显然这是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 I.D. *number*" unless id =~ /\d+/

然后consider whether you want a default valuewhether the value is in the right range等。当接收ID时,我倾向于使用the regex syntax for routes,因为它也会停止跟踪子路由,同时提供一些简单的类型检查:

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)

答案 1 :(得分:0)

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