补丁& Rails升级中的PUT路由

时间:2015-12-02 08:08:43

标签: ruby-on-rails ruby-on-rails-3 rspec routes put

好,

我正在将Rails 3应用程序从Rails 3.2升级到Rails 4.2。在阅读升级说明和更改后,我们遇到了一些PUTPATCH路由的奇怪问题。

在我们的Rails 3应用程序中,我们定义了以下路由:

resources :entities, except: [:show] do
  member do
    put :change_monitoring_status
  end
 end

运行rake routes时,change_monitoring_status路由显示为正确的PUT路由。使用Rails助手为此生成的表单在Rails 3中生成正确的请求。

然而,在Rails 4中,此表单现在正在生成PATCH路由。这完全可以,因为这是Rails中的标准行为。但是,当我们在Rails 4 Production上使用该表单时,会产生404 - Not Found

我们尝试为此编写RSpec测试以模仿相同的行为并关闭错误标记。因此,对于我们的Rails 4升级,我们编写了以下测试:

describe '#change_monitoring_status' do

  before(:each) do
    sign_in user
  end

  it 'fails when put is used' do
    expect {
      put :change_monitoring_status, id: entity.id, _method: "PUT", form_object: {  }
    }.to raise_error
  end

  it 'works when patch is used' do
    expect {
      patch :change_monitoring_status, id: supplier.id, _method: "PATCH", form_object: {  }
    }.to_not raise_error
  end
end

我们现在也将路线改为PATCH而不是PUT

这是我们看到的行为:

  • {4}上的PUT测试失败,因为没有引发404
  • PATCH测试成功
  • PUT请求适用于制作
  • PATCH请求生产失败

我们理解这一点的方式与文档不符。该表单正在生成一个正确的PATCH请求,但我们无法在RSpec测试中获得正确的行为。

我们的期望:

  • PUT筹集404
  • PATCH成功

使用的宝石: * Rails 4.2 * RSpec 3.4 * RSpec-rails 3.4 * simple_form 3.2

1 个答案:

答案 0 :(得分:3)

控制器规范假冒整个请求周期。请求永远不会真正到达路由层 - RSpec只在路由文件中查找与控制器和操作匹配的路由。

虽然这对速度有好处,因为你跳过整个Rack层,它有时会掩盖路由错误。

您的规格也略有不同;第一个使用id: entity.id,而后者使用id: supplier.id

在这种情况下,我会使用routing spec或请求规范,因为这会导致路由层出错 - 在控制器匹配之前。

describe "change_monitoring_status", type: :routing do

  it 'fails when put is used' do
    expect(puts: "/entity/37/change_monitoring_status").not_to be_routable
  end

  it 'works when patch is used' do
    expect(patch: "/entity/37/change_monitoring_status").to 
      route_to(
         controller: "entities", 
         action: "change_monitoring_status", 
         id: 37
      )
  end
end