在块之前更改 Sinatra 中的参数
Altering params in Sinatra before blocks
我正在尝试更改 Sinatra 中 before
块中的请求参数。
似乎在使用这种语法时有效:
before do
@params['global-before'] = 'yes'
end
但是当使用这个语法时,它不起作用:
before '/:id/test' do
@params['route-before'] = 'yes'
end
这是一个完整的例子:
# 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
然后运行:
$ ruby test.rb
$ curl localhost:3000
{"global-before":"yes"}
$ curl localhost:3000/123/test
{"global-before":"yes","id":"123"}
我期待看到 params['route-before']
也被填充。
我试过使用 request.params
而不是 @params
但那根本不起作用。
有人能解释一下吗?
更新:
在 Sinatra 的问题跟踪器中打开了一个 issue
路由过滤器先行,它有路由参数:{"id"=>"123"}
,所以this发生:
original, @params = @params, @params.merge(params) if params.any?
其中 original
最终为 {}
,@params
最终为 {"id"=>"123"}
。当全局过滤器运行时,没有路由参数,因此 original
保持未分配状态 (nil
) 并且 @params
是最初存在的 {}
。
过滤处理后,在ensure
子句中,有this:
@params = original if original
所以全局过滤器会跳过它,因为 original
是 nil
,因为没有路由参数。路由过滤器将 @params
重置为过滤器 运行 之前的任何值,因为保留了 original
,因为存在路由参数。
我不能说这是错误还是预期行为,但至少是 "how",如果不是 "why"。询问 Sinatra team(并在此处报告判决结果)可能是有意义的。
tl;dr:如果过滤器的路径模式中有参数,@params
将重置为过滤器前状态。
注意:您可以通过创建自己的实例变量来绕过它:
before '/:id/test' do
@route_before = 'yes'
end
get '/:id/test' do
"Did we run route before? #{@route_before}"
end
我正在尝试更改 Sinatra 中 before
块中的请求参数。
似乎在使用这种语法时有效:
before do
@params['global-before'] = 'yes'
end
但是当使用这个语法时,它不起作用:
before '/:id/test' do
@params['route-before'] = 'yes'
end
这是一个完整的例子:
# 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
然后运行:
$ ruby test.rb
$ curl localhost:3000
{"global-before":"yes"}
$ curl localhost:3000/123/test
{"global-before":"yes","id":"123"}
我期待看到 params['route-before']
也被填充。
我试过使用 request.params
而不是 @params
但那根本不起作用。
有人能解释一下吗?
更新:
在 Sinatra 的问题跟踪器中打开了一个 issue
路由过滤器先行,它有路由参数:{"id"=>"123"}
,所以this发生:
original, @params = @params, @params.merge(params) if params.any?
其中 original
最终为 {}
,@params
最终为 {"id"=>"123"}
。当全局过滤器运行时,没有路由参数,因此 original
保持未分配状态 (nil
) 并且 @params
是最初存在的 {}
。
过滤处理后,在ensure
子句中,有this:
@params = original if original
所以全局过滤器会跳过它,因为 original
是 nil
,因为没有路由参数。路由过滤器将 @params
重置为过滤器 运行 之前的任何值,因为保留了 original
,因为存在路由参数。
我不能说这是错误还是预期行为,但至少是 "how",如果不是 "why"。询问 Sinatra team(并在此处报告判决结果)可能是有意义的。
tl;dr:如果过滤器的路径模式中有参数,@params
将重置为过滤器前状态。
注意:您可以通过创建自己的实例变量来绕过它:
before '/:id/test' do
@route_before = 'yes'
end
get '/:id/test' do
"Did we run route before? #{@route_before}"
end