从 Rails 4 迁移到 Rails 5:使用 ActionDispatch::Request.parameter_parsers 和 config.middleware
Migrating from Rails 4 to Rails 5: using ActionDispatch::Request.parameter_parsers and config.middleware
我目前正在将应用程序从 Rails 4 迁移到 Rails 5。
我在尝试发出诸如 bundle exec rspec spec
之类的命令时遇到了以下问题:
/Users/me/.rvm/gems/ruby-2.2.2/gems/actionpack-5.1.4/lib/action_dispatch/middleware/stack.rb:35:in `build': undefined method `new' for ActionDispatch::ParamsParser:Module (NoMethodError)
from /Users/me/.rvm/gems/ruby-2.2.2/gems/actionpack-5.1.4/lib/action_dispatch/middleware/stack.rb:99:in `block in build'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/actionpack-5.1.4/lib/action_dispatch/middleware/stack.rb:99:in `each'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/actionpack-5.1.4/lib/action_dispatch/middleware/stack.rb:99:in `inject'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/actionpack-5.1.4/lib/action_dispatch/middleware/stack.rb:99:in `build'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/engine.rb:508:in `block in app'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/engine.rb:504:in `synchronize'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/engine.rb:504:in `app'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/application/finisher.rb:45:in `block in <module:Finisher>'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/initializable.rb:30:in `instance_exec'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/initializable.rb:30:in `run'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/initializable.rb:59:in `block in run_initializers'
from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:226:in `block in tsort_each'
from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:348:in `block (2 levels) in each_strongly_connected_component'
from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:429:in `each_strongly_connected_component_from'
from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:347:in `block in each_strongly_connected_component'
from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:345:in `each'
from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:345:in `call'
from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:345:in `each_strongly_connected_component'
from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:224:in `tsort_each'
from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:203:in `tsort_each'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/initializable.rb:58:in `run_initializers'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/application.rb:353:in `initialize!'
from /Users/me/Documents/mikamai/surveyeah/config/environment.rb:5:in `<top (required)>'
from /Users/me/Documents/mikamai/surveyeah/spec/rails_helper.rb:4:in `require'
from /Users/me/Documents/mikamai/surveyeah/spec/rails_helper.rb:4:in `<top (required)>'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration.rb:1455:in `require'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration.rb:1455:in `block in requires='
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration.rb:1455:in `each'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration.rb:1455:in `requires='
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration_options.rb:112:in `block in process_options_into'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration_options.rb:111:in `each'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration_options.rb:111:in `process_options_into'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration_options.rb:21:in `configure'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/runner.rb:99:in `setup'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/runner.rb:86:in `run'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/runner.rb:71:in `run'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/runner.rb:45:in `invoke'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/exe/rspec:4:in `<top (required)>'
from /Users/me/.rvm/gems/ruby-2.2.2/bin/rspec:23:in `load'
from /Users/me/.rvm/gems/ruby-2.2.2/bin/rspec:23:in `<main>'
from /Users/me/.rvm/gems/ruby-2.2.2/bin/ruby_executable_hooks:15:in `eval'
from /Users/me/.rvm/gems/ruby-2.2.2/bin/ruby_executable_hooks:15:in `<main>'
我认为问题来自文件 application.rb
,其中包含:
module MyApp
class Application < Rails::Application
config.middleware.insert_before ActionDispatch::ParamsParser, 'CatchJsonParseErrors'
end
end
我试图将该行更改为:
module MyApp
class Application < Rails::Application
config.middleware.use ActionDispatch::ParamsParser, 'CatchJsonParseErrors'
end
end
但它并没有解决问题。我看了一下 Rails 5 release notes 好像是
ActionDispatch::ParamsParser is deprecated and was removed from the
middleware stack. To configure the parameter parsers use
ActionDispatch::Request.parameter_parsers=.
虽然我不确定我会如何使用它。
app/middleware/catch_json_parse_errors.rb 文件如下所示:
class CatchJsonParseErrors
def initialize(app)
@app = app
end
def call(env)
begin
@app.call(env)
rescue ActionDispatch::ParamsParser::ParseError => error
if env['HTTP_ACCEPT'] =~ /application\/json/
error_output = "There was a problem in the JSON you submitted: #{error}"
return [
400, { "Content-Type" => "application/json" },
[ { status: 400, error: error_output }.to_json ]
]
else
raise error
end
end
end
end
有人知道我如何为 Rails 5 更新此中间件配置吗?非常感谢任何帮助! :D 提前致谢
修复此问题:
module MyApp
class Application < Rails::Application
require './lib/middleware/catch_json_parse_errors.rb'
config.middleware.insert_before Rack::Head, CatchJsonParseErrors
end
end
和我的lib/middleware/catch_json_parse_errors.rb:
class CatchJsonParseErrors
def initialize(app)
@app = app
end
def call(env)
begin
@app.call(env)
rescue ActionDispatch::Http::Parameters::ParseError => error
if env['HTTP_ACCEPT'] =~ /application\/json/
error_output = "There was a problem in the JSON you submitted: #{error}"
return [
400, { "Content-Type" => "application/json" },
[ { status: 400, error: error_output }.to_json ]
]
else
raise error
end
end
end
end
请注意,我还必须在此处将 ActionDispatch::ParamsParser::ParseError
更改为 ActionDispatch::Http::Parameters::ParseError
。在 ./lib/middleware/
中可能有更好的加载中间件文件的方法,但这暂时有效。
我目前正在将应用程序从 Rails 4 迁移到 Rails 5。
我在尝试发出诸如 bundle exec rspec spec
之类的命令时遇到了以下问题:
/Users/me/.rvm/gems/ruby-2.2.2/gems/actionpack-5.1.4/lib/action_dispatch/middleware/stack.rb:35:in `build': undefined method `new' for ActionDispatch::ParamsParser:Module (NoMethodError)
from /Users/me/.rvm/gems/ruby-2.2.2/gems/actionpack-5.1.4/lib/action_dispatch/middleware/stack.rb:99:in `block in build'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/actionpack-5.1.4/lib/action_dispatch/middleware/stack.rb:99:in `each'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/actionpack-5.1.4/lib/action_dispatch/middleware/stack.rb:99:in `inject'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/actionpack-5.1.4/lib/action_dispatch/middleware/stack.rb:99:in `build'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/engine.rb:508:in `block in app'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/engine.rb:504:in `synchronize'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/engine.rb:504:in `app'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/application/finisher.rb:45:in `block in <module:Finisher>'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/initializable.rb:30:in `instance_exec'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/initializable.rb:30:in `run'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/initializable.rb:59:in `block in run_initializers'
from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:226:in `block in tsort_each'
from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:348:in `block (2 levels) in each_strongly_connected_component'
from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:429:in `each_strongly_connected_component_from'
from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:347:in `block in each_strongly_connected_component'
from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:345:in `each'
from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:345:in `call'
from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:345:in `each_strongly_connected_component'
from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:224:in `tsort_each'
from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:203:in `tsort_each'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/initializable.rb:58:in `run_initializers'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/application.rb:353:in `initialize!'
from /Users/me/Documents/mikamai/surveyeah/config/environment.rb:5:in `<top (required)>'
from /Users/me/Documents/mikamai/surveyeah/spec/rails_helper.rb:4:in `require'
from /Users/me/Documents/mikamai/surveyeah/spec/rails_helper.rb:4:in `<top (required)>'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration.rb:1455:in `require'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration.rb:1455:in `block in requires='
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration.rb:1455:in `each'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration.rb:1455:in `requires='
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration_options.rb:112:in `block in process_options_into'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration_options.rb:111:in `each'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration_options.rb:111:in `process_options_into'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration_options.rb:21:in `configure'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/runner.rb:99:in `setup'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/runner.rb:86:in `run'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/runner.rb:71:in `run'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/runner.rb:45:in `invoke'
from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/exe/rspec:4:in `<top (required)>'
from /Users/me/.rvm/gems/ruby-2.2.2/bin/rspec:23:in `load'
from /Users/me/.rvm/gems/ruby-2.2.2/bin/rspec:23:in `<main>'
from /Users/me/.rvm/gems/ruby-2.2.2/bin/ruby_executable_hooks:15:in `eval'
from /Users/me/.rvm/gems/ruby-2.2.2/bin/ruby_executable_hooks:15:in `<main>'
我认为问题来自文件 application.rb
,其中包含:
module MyApp
class Application < Rails::Application
config.middleware.insert_before ActionDispatch::ParamsParser, 'CatchJsonParseErrors'
end
end
我试图将该行更改为:
module MyApp
class Application < Rails::Application
config.middleware.use ActionDispatch::ParamsParser, 'CatchJsonParseErrors'
end
end
但它并没有解决问题。我看了一下 Rails 5 release notes 好像是
ActionDispatch::ParamsParser is deprecated and was removed from the middleware stack. To configure the parameter parsers use ActionDispatch::Request.parameter_parsers=.
虽然我不确定我会如何使用它。
app/middleware/catch_json_parse_errors.rb 文件如下所示:
class CatchJsonParseErrors
def initialize(app)
@app = app
end
def call(env)
begin
@app.call(env)
rescue ActionDispatch::ParamsParser::ParseError => error
if env['HTTP_ACCEPT'] =~ /application\/json/
error_output = "There was a problem in the JSON you submitted: #{error}"
return [
400, { "Content-Type" => "application/json" },
[ { status: 400, error: error_output }.to_json ]
]
else
raise error
end
end
end
end
有人知道我如何为 Rails 5 更新此中间件配置吗?非常感谢任何帮助! :D 提前致谢
修复此问题:
module MyApp
class Application < Rails::Application
require './lib/middleware/catch_json_parse_errors.rb'
config.middleware.insert_before Rack::Head, CatchJsonParseErrors
end
end
和我的lib/middleware/catch_json_parse_errors.rb:
class CatchJsonParseErrors
def initialize(app)
@app = app
end
def call(env)
begin
@app.call(env)
rescue ActionDispatch::Http::Parameters::ParseError => error
if env['HTTP_ACCEPT'] =~ /application\/json/
error_output = "There was a problem in the JSON you submitted: #{error}"
return [
400, { "Content-Type" => "application/json" },
[ { status: 400, error: error_output }.to_json ]
]
else
raise error
end
end
end
end
请注意,我还必须在此处将 ActionDispatch::ParamsParser::ParseError
更改为 ActionDispatch::Http::Parameters::ParseError
。在 ./lib/middleware/
中可能有更好的加载中间件文件的方法,但这暂时有效。