简体   繁体   中英

Rails 4 / Rack disregarding _method override parameter

I have a Rails 4 application with a shallow nested route:

  resources :funds do
    resources :fund_mappings, shallow: true
  end

I understand that PATCH /fund_mappings/(:id) should match FundMappingController#update because the route is shallow (so only the routes for new and create will actually contain /fund/ at the beginning). Indeed, this route is listed in the output of rake:routes :

PATCH   /fund_mappings/:id(.:format)    fund_mappings#update

Of course browsers don't really work with PUT, PATCH or DELETE so there's a hack in Rack (I believe) which should swap out the HTTP method for the contents of the _method HTTP parameter.

So when I went to update a record and got this error:

No route matches [POST] "/fund_mappings/1"

I thought that the form I was submitting didn't have the _method field with the value patch . So I inspected the form, and there was such a field with that value. Also, the Rails error page indicated that it came through fine:

{
 "utf8"=>"✓",
 "_method"=>"patch",
 "authenticity_token"=>"stuff",
 "fund_mapping"=> {
   "key"=>"asdf",
   "source_id"=>"1"
 },
 "commit"=>"Save"
}

So why is Rails (or Rack) thinking that this is a POST request?

It turns out that including the gem rails-api in my Gemfile caused this. I have an API part of my application, and a human UI part, so I had created an ApiController which inherited from ActionController::API (from the gem) for the API stuff. Separately, I had an ApplicationController which inherited from ActionController::Base just like normal for the human UI stuff. I thought that the rails-api related stuff would be confined to the ApiController -- turns out that's wrong.

rails-api and rails aren't meant to coexist, and it breaks many things if you try. However if you set your application's config.api_only = false (by default, it's true), then it stops breaking this part.

The combination of these two lines in rails-api was causing this issue:

setting config.api_only = true

don't include Rack::MethodOverride in the middleware stack for the application if config.api_only = true

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM