首页 > 解决方案 > 在块之前更改 Sinatra 中的参数

问题描述

我正在尝试更改beforeSinatra 块中的请求参数。

似乎在使用这种语法时,它可以工作:

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 的问题跟踪器中打开了一个问题

标签: rubysinatra

解决方案


路由过滤器先行,它有路由参数:{"id"=>"123"},所以会发生这种情况:

original, @params = @params, @params.merge(params) if params.any?

whereoriginal以 as{}@paramsas结尾{"id"=>"123"}。当全局过滤器运行时,没有路由参数,所以original保持未分配 ( nil) 并且@params{}最初存在的那个。

在过滤器处理之后,在ensure子句中,有这样的:

@params = original if original

所以全局过滤器会跳过它,因为originalis nil,因为没有路由参数。路由过滤器将 重置为@params过滤器运行之前的任何值,因为original保留,因为有路由参数。

我不能说这是一个错误还是一个预期的行为,但它至少是一个“如何”,如果不是“为什么”的话。询问Sinatra 团队(并在此处报告结论)可能是有道理的。

tl;dr:@params如果过滤器的路径模式中有参数,则重置为过滤前状态。

注意:您可以通过创建自己的实例变量来解决它:

before '/:id/test' do
  @route_before = 'yes'
end

get '/:id/test' do
  "Did we run route before? #{@route_before}"
end

推荐阅读