Home > Blockchain >  how should I test whether a route has params in Sinatra?
how should I test whether a route has params in Sinatra?

Time:12-09

In a Sinatra app, I have many routes that use a date. They are all formatted:

get '/foo/:bar/:year/:month' do
    # code
end

I want to create a before hook setting a requested date according to the route params. This shouldn't run if the route doesn't have month and year params.

I tried this:

before do
    if params[:year].any? && params[:month].any?
        @requested_date = Date.new(params[:year].to_i, params[:month].to_i, 01)
    end
end

and this:

before do
    if defined?(params[:year]) && defined?(params[:month])
        @requested_date = Date.new(params[:year].to_i, params[:month].to_i, 01)
    end
end

But I keep running into the same error: Date::Error - invalid date:

CodePudding user response:

To reliably check if params hash have year/month keys you can use Hash#key?, smth. like:

before do
  if params.key?(:year) && params.key?(:month)
    <set date>
  end
end

But there is still a problem. The route '/foo/:bar/:year/:month' will match things like /foo/bar/baz/qux with Sinatra router resolving params to { bar: 'bar', year: 'baz', month: 'qux'}.

So you still cannot just feed the params to Date constructor and expect it to give a valid date for you. In simplest case you can just write a helper method like

def build_date(year, month)
  Date.new(year.to_i, month.to_i, 01)
rescue Date::Error
  # So what now?
end

and use it in your before block, but another question arise - what to do in case of an error? The easiest solution is to just respond with 404, but you might need something more sophisticated (for example, to communicate the invalid date format to the user).

Another thing to mention is Sinatra's capability to match routes using regexps: for example, you could force Sinatra router to recognize only routes that contain 4 digits for year and integers in range 1-12 for month. I'd probably avoid it (makes routes harder to reason about, also accessing the matched params becomes a bit cluttered), but still a good thing to remember about...

  • Related