Sinatra matches params[:id] as string type, additional conversion needed to match the database id?

隐身守侯 提交于 2019-12-11 10:15:57

问题


I am using sinatra and DataMapper to access an sqlite3 database. I always get an nil when calling get(params[:id]). But when I call get(params[:id].to_i) I can get the right record. Is there anything wrong such that I have to do the conversion explicitly?

The sinatra app is simple:

class Record
  include DataMapper::Resource
  property :id, Serial
  ....
end

get '/list/:id' do
  r = Record.get(params[:id])
  ...
end

回答1:


Obviously this is a problem with Datamapper (if you believe it should be casting strings to numbers for id's), but there are ways Sinatra can mitigate it. When params come in you need to check:

  • They exist.
  • They're the right type (or castable).
  • They're within the range of values required or expected.

For example:

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


curl http://example.org/list/ddd

That won't work well, better to check and return an error message:

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

Then consider whether you want a default value, whether the value is in the right range etc. When taking in ID's I tend to use the regex syntax for routes, as it stops following sub routes being gobbled up too, while providing a bit of easy type checking:

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

Helpers are also useful in this situation:

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)



回答2:


To clarify, the comment in the original question by @mbj is correct. This is a bug in dm-core with Ruby 2.0. It worked fine with ruby 1.9. You are likely on dm-core version 1.2 and need 1.2.1, which you can get by running 'gem update dm-core'.



来源:https://stackoverflow.com/questions/16304097/sinatra-matches-paramsid-as-string-type-additional-conversion-needed-to-matc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!