【问题标题】:Rails 4 Method Not Allowed after Upgrading from Rails 3从 Rails 3 升级后不允许使用 Rails 4 方法
【发布时间】:2015-08-09 16:07:39
【问题描述】:

我有一个现有的代码库,我正在尝试从 Rails 3.2 升级到 Rails 4.0

我有一个名为 assets_controller 的控制器,带有一个“创建”方法,并且我的路由文件中有一个条目:

resources :assets

在前端使用 jQuery 进行 ajax,如果我从浏览器向“/assets”发送一个 post 请求,我会得到 405(不允许的方法):

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

这在 Rails 3 中运行良好,但我似乎无法弄清楚问题所在。

更新:

这是我的控制器的简化版本:

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

这是'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

这是我的开发日志:

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

(是的,这就是所有日志)

发布数据: { "asset_type":"文档", “标题”:“DNS”, "heading_id":9999, “受版权保护”:假, "url":"https://confidental.url", "pubtitle":"DNS", "作者":""}

另一个编辑: 出于诊断目的,我注释掉了我的整个路由文件,这些是进行一些手动测试的结果:

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)

资产是 Rails 4 中的某种保留端点吗?

【问题讨论】:

  • 这可能只是一种预感,但 rails 4 会检查跨站点请求伪造。这意味着您不能在没有 csrf 令牌的情况下发布到路由。您应该提供有关该问题的更多详细信息。就像控制器代码以及 asset 数据看起来像您正在发布到控制器一样。 Rails 4 安全指南:guides.rubyonrails.org/security.html
  • 我在控制器中添加了“skip_before_filter:verify_authenticity_token”,我认为这应该跳过任何 csrf 令牌验证,但这似乎没有帮助。
  • @JensD 我已经添加了请求的信息
  • denodster 您可能会尝试从具有强参数的 params 哈希中请求参数。 Rails 4 引入了强参数作为强制表单帖子包含某些白名单值的手段。 edgeapi.rubyonrails.org/classes/ActionController/…
  • 我的 Gemfile 中有 gem 'protected_attributes',所以在升级到 rails 4.1 之前我不必担心这个

标签: jquery ajax ruby-on-rails-4 routes


【解决方案1】:

原来问题出在“资产”这个名称上,我找不到任何文档来确认这一点,但是将资产模型和控制器重命名为其他名称可以解决问题。

【讨论】:

  • 这方面的结果相同。我选择了将路由包装在范围内的惰性修复。
  • 您的模型是否专门称为“资产”?
  • 是的,但问题看起来像是来自路由名称本身。将其定义为 scope :something do resources :assets end 是我能想到的最简单的解决方法,并且不会影响控制器或模型名称以及视图文件夹结构。
  • 哇,谢谢,这需要一段时间才能弄清楚! ;)
【解决方案2】:

这不仅仅是assets 这个词。 Rails 不喜欢路由路径和资产目录在同一个子目录中。

发出帖子请求时,您将收到method not allowed。问题是路径和资产目录不能重叠。问题特别在于该路径中的POST 请求。我假设在 Rails 的某个地方,他们必须禁用所有对资产目录的非 GET 请求。


在下面这个非常简单的应用程序中,您将收到method not allowed 错误。因为路径 /welcomes 被用于路由和资产前缀。

文件:config/environment/development.rb

config.assets.prefix = '/welcomes'

文件:config/routes.rb

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

文件:app/controllers/welcomes_controller.rb

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

  def create
    @welcome = 'world';
  end
end

文件:app/views/welcomes/index.html.rb

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

文件:app/views/welcomes/create.html.rb

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

【讨论】:

【解决方案3】:

问题是您的asset 控制器路由与rails 默认/assets 路径冲突。

最简单的解决方案是将您的config/routes.rb 文件行修改为如下所示(或您选择的任何其他不是assets 的路径):

resources :assets, path: 'site_assets'

【讨论】:

    猜你喜欢
    • 2019-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多