Rails 4 Method Not Allowed after Upgrading from Ra

2019-06-17 10:22发布

问题:

I've got an existing codebase that I'm attempting to upgrade from Rails 3.2 to Rails 4.0

I have controller called assets_controller with a 'create' method and I have a an entry in my routes file:

resources :assets

Using jQuery for ajax on the front end, if I send a post request to '/assets' from a browser, I get 405 (Method Not Allowed):

$.ajax({method: 'POST', data: asset, url: '/assets' });

This worked just fine in Rails 3, and I can't seem to figure out what the issue is.

Updates:

Heres a simplified version of my controller:

class AssetsController < ApplicationController
  skip_before_filter :verify_authenticity_token 
    def create
        # params[:assets] is passed if a mass addition of assets (i.e. book) occurs
        assets = []
        if params[:assets]
          assets = params[:assets]
        else
          assets.push params
        end

        last_asset_id = 0

        assets.each do |asset_data|
          asset = Object.const_get(asset_data[:asset_type]).new(asset_data)
          if !asset.save
            json_false_errors(asset.errors.full_messages)
            return
          else
            last_asset_id = asset.id
          end
        end
      end
end

Heres the output from 'rake routes'

 assets GET        /assets(.:format)                                        assets#index
                                          POST       /assets(.:format)                                        assets#create
                                new_asset GET        /assets/new(.:format)                                    assets#new
                               edit_asset GET        /assets/:id/edit(.:format)                               assets#edit
                                    asset GET        /assets/:id(.:format)                                    assets#show
                                          PATCH      /assets/:id(.:format)                                    assets#update
                                          PUT        /assets/:id(.:format)                                    assets#update
                                          DELETE     /assets/:id(.:format)                                    assets#destroy

Heres my development log:

Started POST "/assets" for 127.0.0.1 at 2015-05-27 09:39:42 -0400

(yeah thats all the log has)

POST DATA: { "asset_type":"Document", "title":"DNS", "heading_id":9999, "copyrighted":false, "url":"https://confidental.url", "pubtitle":"DNS", "author":""}

Another Edit: I commented out my entire routes file for diagnostic purposes, these are the results of doing some manual testing:

POST http://localhost:8000/assets 405 (Method Not Allowed)
POST http://localhost:8000/asset 404 (Not Found)
POST http://localhost:8000/ass 404 (Not Found)

is assets some sort of reserved endpoint in rails 4?

回答1:

This isn't just about the word assets. Rails does not like when a route path and the asset directory are in the same subdirectory.

When making a post request, you will get method not allowed. The problem is there can be no overlap with paths and the asset directory. The problem is specifically with POST requests in that path. I am assuming somewhere in rails, they must have disabled all non-GET requests for the assets directory.


In this very simple app below, you will get a method not allowed error. Because the path /welcomes is being used for a route and for an asset prefix.

File: config/environment/development.rb

config.assets.prefix = '/welcomes'

File: config/routes.rb

resources :welcomes, path: 'welcomes', only: ['index', 'create']

File: app/controllers/welcomes_controller.rb

class WelcomesController < ApplicationController
  def index
    @welcome = 'hello';
  end

  def create
    @welcome = 'world';
  end
end

File: app/views/welcomes/index.html.rb

<%= form_for(@welcome) do |f| %>
    <%= f.submit 'Submit' %>
<% end %>

File: app/views/welcomes/create.html.rb

<h1>Welcomes#create</h1>
<p>Find me in app/views/welcomes/create.html.erb</p>


回答2:

It turns out the problem was with the name 'assets' I can't find any documentation to confirm this, but renaming the asset model and controller to something else fixed the problem.



回答3:

The issue is that your asset controller routes are conflicting with the rails default /assets path.

The simplest solution is to modify your config/routes.rb file line to read as follows (or any other path of your choosing that is not assets):

resources :assets, path: 'site_assets'