I am trying to alter the request params in a before block in Sinatra.
It seems that when using this syntax, it works:
before do
@params['global-before'] = 'yes'
end
But when using this syntax, it does not work:
before '/:id/test' do
@params['route-before'] = 'yes'
end
Here is a full example:
# test.rb
require 'sinatra'
require 'sinatra/reloader'
set :bind, '0.0.0.0'
set :port, 3000
before do
@params['global-before'] = 'yes'
end
before '/:id/test' do
@params['route-before'] = 'yes'
end
get '/' do
params.to_json
end
get '/:id/test' do
params.to_json
end
Then running:
$ ruby test.rb
$ curl localhost:3000
{"global-before":"yes"}
$ curl localhost:3000/123/test
{"global-before":"yes","id":"123"}
I was expecting to see the params['route-before'] populated as well.
I have tried using request.params instead of @params but that did not work at all.
Can anyone shed some light on this?
Opened an issue in Sinatra's issue tracker
The route filter goes first, and it has route parameters: {"id"=>"123"}, so this happens:
original, @params = @params, @params.merge(params) if params.any?
where original ends up as {} and @params as {"id"=>"123"}. When the global filter runs, there are no route parameters, so original remains unassigned (nil) and @params is the {} that was originally there.
After the filter processes, in the ensure clause, there is this:
@params = original if original
So global filter skips it, because original is nil, because there were no route parameters. The route filter resets the @params to whatever it was before the filter ran, because original is preserved, because there were route parameters.
I can't say whether this is a bug or an intended behaviour, but it's a "how" at least, if not a "why". It may make sense asking the Sinatra team (and reporting back here with the verdict).
tl;dr: @params are reset to pre-filter state if there are parameters in the filter's path pattern.
Note: you can hack around it by making your own instance variable:
before '/:id/test' do
@route_before = 'yes'
end
get '/:id/test' do
"Did we run route before? #{@route_before}"
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With