Search code examples
ruby-on-railsrubyactiondispatch

ActionDispatch::ParamsParser replacement after upgrade to Rails 5


Migrating an app from Rails 4.2.9 to 5.2.1.

This is latest issue:

$ rails console
/Users/meltemi/rails/myapp/config/initializers/disable_xml_params.rb:3:in `<top (required)>': uninitialized constant ActionDispatch::ParamsParser (NameError)
    from /Users/meltemi/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/railties-5.2.1/lib/rails/engine.rb:657:in `block in load_config_initializer'
    from /Users/meltemi/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/activesupport-5.2.1/lib/active_support/notifications.rb:170:in `instrument'
    from /Users/meltemi/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/railties-5.2.1/lib/rails/engine.rb:656:in `load_config_initializer'

The offending line of code in an initializer:

# config/initializers/disable_xml_params.rb
ActionDispatch::ParamsParser::DEFAULT_PARSERS.delete(Mime::XML)

Rails Guides says:

ActionDispatch::ParamsParser is deprecated and was removed from the middleware stack. To configure the parameter parsers use ActionDispatch::Request.parameter_parsers=. (commit, commit)

So I've tried the following:

ActionDispatch::Request.parameter_parsers.delete(Mime::XML)

But that begets more errors:

$ rails console
/Users/meltemi/rails/myapp/config/initializers/disable_xml_params.rb:3:in `<top (required)>': uninitialized constant Mime::XML (NameError)
    from /Users/meltemi/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/railties-5.2.1/lib/rails/engine.rb:657:in `block in load_config_initializer'
    from /Users/meltemi/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/activesupport-5.2.1/lib/active_support/notifications.rb:170:in `instrument'
    from /Users/meltemi/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/railties-5.2.1/lib/rails/engine.rb:656:in `load_config_initializer'

Is there a better way to call .delete on that object?


Solution

  • You have to grab the existing values from parameter_parsers, modify it to suit your needs, then reset the values to your modified values. From the ActionDispatch::Http::Parameters documentation:

    parameter_parsers=(parsers)

    Configure the parameter parser for a given MIME type.

    It accepts a hash where the key is the symbol of the MIME type and the value is a proc.

    original_parsers = ActionDispatch::Request.parameter_parsers
    xml_parser = -> (raw_post) { Hash.from_xml(raw_post) || {} }
    new_parsers = original_parsers.merge(xml: xml_parser)
    ActionDispatch::Request.parameter_parsers = new_parsers
    

    In your specific case, you should look at the parsers in original_parsers to see if there is anything to delete. On a simple Rails 5 app that I have handy to look at, the only values I have are:

    => {
        :json => #<Proc:0x00007fe818fc6fb8@/Users/foo/.rvm/gems/ruby-2.6.0-preview2/gems/actionpack-5.2.1/lib/action_dispatch/http/parameters.rb:11 (lambda)>
    }
    

    Your app's configuration is likely different, but to answer your question about how to delete a value, this simple version should work:

    ActionDispatch::Request.parameter_parsers = ActionDispatch::Request.parameter_parsers.except(:json)
    

    You may find additional useful information in this answer.