Rails 升级中的 PATCH 和 PUT 路由
PATCH & PUT routes in Rails upgrade
好的,
我正在将我们的 Rails 3 应用程序从 Rails 3.2 升级到 Rails 4.2。阅读升级说明和更改后,我们 运行 遇到了一些 PUT
和 PATCH
路由的奇怪问题。
在我们的 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
。
这是我们看到的行为:
PUT
测试在 Rails 4 上失败,因为没有引发 404
PATCH
测试成功
PUT
请求在生产中有效
PATCH
请求在生产环境中失败
我们的理解方式与文档不符。表单正在生成正确的 PATCH
请求,但我们无法在 RSpec 测试中获得正确的行为。
我们的期望:
PUT
养个404
PATCH
成功
使用的宝石:
* Rails 4.2
* RSpec 3.4
* RSpec-rails 3.4
* simple_form 3.2
控制器规范伪造整个请求周期。请求从未真正到达路由层 - RSpec 只是在路由文件中查找与控制器和操作匹配的路由。
虽然这对速度有好处,因为您跳过了整个机架层,但它有时会掩盖路由错误。
您的规格也略有不同;第一个使用 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
好的,
我正在将我们的 Rails 3 应用程序从 Rails 3.2 升级到 Rails 4.2。阅读升级说明和更改后,我们 运行 遇到了一些 PUT
和 PATCH
路由的奇怪问题。
在我们的 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
。
这是我们看到的行为:
PUT
测试在 Rails 4 上失败,因为没有引发 404PATCH
测试成功PUT
请求在生产中有效PATCH
请求在生产环境中失败
我们的理解方式与文档不符。表单正在生成正确的 PATCH
请求,但我们无法在 RSpec 测试中获得正确的行为。
我们的期望:
PUT
养个404PATCH
成功
使用的宝石: * Rails 4.2 * RSpec 3.4 * RSpec-rails 3.4 * simple_form 3.2
控制器规范伪造整个请求周期。请求从未真正到达路由层 - RSpec 只是在路由文件中查找与控制器和操作匹配的路由。
虽然这对速度有好处,因为您跳过了整个机架层,但它有时会掩盖路由错误。
您的规格也略有不同;第一个使用 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