Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sinatra/Ruby default a parameter

Tags:

ruby

sinatra

Is there a way to default a parameter in Sinatra?

I am currently looking to see if 'start' was passed as a parameter, but it seems a little hacky. It would be nice if I could tell Sinatra to default certain parameters if they are not specified.

get '/comments/?' do
   # want to setup page stuff, default to first page if not specified
   params[:start] = 0 if !params[:start] 
end

Any ideas?

like image 462
lostintranslation Avatar asked Feb 14 '13 20:02

lostintranslation


2 Answers

It's true that you can use ||= in this way, but it's a very strange thing to set the params after retrieving them. It's more likely you'll be setting variables from the params. So instead of this:

params[:start] ||= 0

surely you're more likely to be doing this:

start = params[:start] || 0

and if you're going to do that then I'd suggest using fetch

start = params.fetch :start, 0

If you're really looking for default values in the parameters hash before a route, then use a before filter

before "/comments/?" do
  params[:start] ||= 0
end

Update:

If you're taking a parameter from the route pattern then you can give it a default argument by using block parameters, because Ruby (from v1.9) can take default parameters for blocks, e.g.

get "/comments/:start/?" do |start=0|
  # rest of code here
end

The start parameter will be available via the start local variable (given to the block) or via params[:captures].first (see the docs for more on routes).


Further update:

When you pass a route to a verb method (e.g. get) the Sinatra will use that route to match incoming requests against. Requests that match fire the block given, so a simple way to make clear that you want some defaults would be:

get "/comments/?" do
  defaults = {start: 10, finish: 20}
  params = defaults.merge params
  # more code follows…
end

If you want it to look cleaner, use a helper:

helpers do
  def set_defaults( defaults={} )
    warn "Entering set_defaults"
    # stringify_keys!
    h = defaults.each_with_object({}) do |(k,v),h|
      h[k.to_s] = defaults[k]
    end
    params.merge!( h.merge params )
  end
end

get "/comments/?" do
  set_defaults start: 10, finish: 20
  # more code follows…
end

If you need something more heavyweight, try sinatra-param.


Sinatra::DefaultParameters gem

I liked this bit of code so much I've turned it into a gem.

like image 195
ian Avatar answered Sep 22 '22 19:09

ian


You can use the "or equals" operator here: params[:start] ||= 0

http://www.rubyinside.com/what-rubys-double-pipe-or-equals-really-does-5488.html

like image 29
Patrick Lewis Avatar answered Sep 23 '22 19:09

Patrick Lewis