Permalink
Browse files

Improve upgrade guide documentation about the PUT->PATCH change

  • Loading branch information...
1 parent 0512286 commit f308e3c1030c6540018e8f5932dae112f978c3b7 @trevorturk trevorturk committed Jun 3, 2013
Showing with 39 additions and 16 deletions.
  1. +39 −16 guides/source/upgrading_ruby_on_rails.md
View
55 guides/source/upgrading_ruby_on_rails.md
@@ -24,41 +24,64 @@ TIP: Ruby 1.8.7 p248 and p249 have marshaling bugs that crash Rails. Ruby Enterp
### HTTP PATCH
-Rails 4 now uses `PATCH` as the primary HTTP verb for updates. When a resource
-is declared in `config/routes.rb`:
+Rails 4 now uses `PATCH` as the primary HTTP verb for updates when a RESTful
+resource is declared in `config/routes.rb`. The `update` action is still used,
+and `PUT` requests will continue to be routed to the `update` action as well.
+So, if you're using only the standard RESTful routes, no changes need to be made:
```ruby
resources :users
```
-the action in `UsersController` to update a user is still `update`.
+```erb
+<%= form_for @user do |f| %>
+```
-`PUT` requests to `/users/:id` in Rails 4 get routed to `update` as they are
-today. So, if you have an API that gets real PUT requests it is going to work.
-The router also routes `PATCH` requests to `/users/:id` to the `update` action.
+```ruby
+class UsersController < ApplicationController
+ def update
+ # No change needed; PATCH will be preferred, and PUT will still work.
+ end
+end
+```
-So, in Rails 4 both `PUT` and `PATCH` are routed to update. We recommend
-switching to `PATCH` as part of your upgrade process if possible, as it's more
-likely what you want.
+However, you will need to make a change if you are using `form_for` to update
+a resource in conjunction with a custom route using the `PUT` HTTP method:
-Note, when using `form_for` to update a resource in conjunction with a custom route,
-you'll need to update your route to explicity match the `patch` verb:
+```ruby
+resources :users, do
+ put :update_name, on: :member
+end
+```
```erb
<%= form_for [ :update_name, @user ] do |f| %>
- ...
-<% end %>
```
```ruby
+class UsersController < ApplicationController
+ def update_name
+ # Change needed; form_for will try to use a non-existant PATCH route.
+ end
+end
+```
+
+If the action is not being used in a public API and you are free to change the
+HTTP method, you can update your route to use `patch` instead of `put`:
+
+```ruby
resources :users do
- # Rails 3
- put :update_name, on: :member
- # Rails 4
patch :update_name, on: :member
end
```
+If the action is being used in a public API and you can't change to HTTP method
+being used, you can update your form to use the `PUT` method instead:
+
+```erb
+<%= form_for [ :update_name, @user ], method: :put do |f| %>
+```
+
For more on PATCH and why this change was made, see [this post](http://weblog.rubyonrails.org/2012/2/25/edge-rails-patch-is-the-new-primary-http-method-for-updates/)
on the Rails blog.

0 comments on commit f308e3c

Please sign in to comment.