Edge Rails: PATCH is the new primary HTTP method for updates »
Created at: 26.02.2012 03:54, source: Riding Rails - home, tagged: Edge Edge http patch REST
What is PATCH?
The HTTP method PUT means resource creation or replacement at some given URL.
Think files, for example. If you upload a file to S3 at some URL, you want either to create the file at that URL or replace an existing file if there's one. That is PUT.
Now let's say a web application has an Invoice model with a paid flag that
indicates whether the invoice has been paid. How do you set that flag in a
RESTful way? Submitting paid=1 via PUT to /invoices/:id does not conform to
the semantics, because such request would not be sending a complete representation of the invoice for replacement.
With the constraints of the methods GET, POST, PUT, DELETE, the traditional answer
is to define the paid flag of a given invoice to be a resource by itself. So,
you define a route to be able to PUT paid=1 to /invoices/:id/paid. You have
to do that because PUT does not allow partial updates to a resource.
Now let's think about ordinary edit forms in typical Ruby on Rails applications.
How many times are we sending a complete representation for replacement? Not
always, perhaps we could say that it is even rare in practice that you do so.
For example, the conventional created_at and updated_at timestamps normally
can't be set by end-users, though they are often considered to belong to the
representation of resources that map to records.
PUT in addition is an idempotent method. You should be able to replay a request as many times as you want and get the same resource, something that sometimes is violated by conventional idioms for creating children resources using nested attributes while updating a parent resource.
There's nothing theoretical preventing PUT from doing partial updates, but when HTTP was being standarized the replacement semantics were already deployed.
Because of that, the PATCH method was defined in 1995 and standarized later. PATCH is a method that is not safe, nor idempotent, and allows full and partial updates and side-effects on other resources.
In practice, as you see, PATCH suits everyday web programming way better than
PUT for updating resources. In Ruby on Rails it corresponds naturally to the way
we use update_attributes for updating records.
Thus, PATCH is going to be the primary method for updates in Rails 4.0.
Routing
This is an important change, but we plan to do it in a way that is backwards compatible.
When a resource is declared in config/routes.rb, for example,
resources :users
the action in UsersController to update a user is still update in Rails 4.0.
PUT requests to /users/:id in Rails 4.0 get routed to update as they are
today. So, if you have an API that gets real PUT requests it is going to work.
In Rails 4.0, though, the router also routes PATCH requests to /users/:id to
the update action.
So, in Rails 4.0 both PUT and PATCH are routed to update.
Forms
Forms of persisted resources:
form_for @user
get "patch" in the hidden field "_method". The RFC is deliberately vague about the way to represent changes in a PATCH request. Submitting a form is perfectly valid, client and server must simply agree on the accepted ways to update a resource.
Let me emphasize that the "_method" hack is a workaround for the limitations in web browsers. As you probably know Rails routes real HTTP methods. That is, actual PUT, DELETE, and now, PATCH requests are routed to their respective actions.
General availability
PATCH requests are available in all places where the rest of the methods are
available today. There is a patch macro for the routes DSL, :via understands
the symbol :patch. Tests can issue PATCH requests, request objects respond to
patch?, etc. Please see the original commit for details (with an important
followup here).
Will my web server understand PATCH?
Yes, it should. I have personally tried Apache, nginx, Phusion Passenger, Unicorn, Thin, and WEBrick. They all understood PATCH requests out of the box.
Also, HTTP clients should be in general able to issue PATCH requests. For example in curl(1) you'd execute:
curl -d'user[name]=wadus' -X PATCH http://localhost:3000/users/1
Credits
We would like to thank David Lee for this contribution and endless patience to keep interested in this even after months of discussion.
Also I would like to highlight the quality of the patch itself. It is excellent: code, tests, all docs revised, comments in code revised. Everything carefully and thoroughly updated. An exemplar patch.
more »
What's new in Edge Rails: EXPLAIN »
Created at: 06.12.2011 23:20, source: Riding Rails - home, tagged: Edge
There are some new features related to EXPLAIN in the forthcoming Ruby on Rails 3.2 we'd like to share:
- Running EXPLAIN manually
- Automatic EXPLAIN for slow queries
- Silencing automatic EXPLAIN
As of this writing they are available for the adapters sqlite3, mysql2, and
postgresql.
Running EXPLAIN Manually
You can now run EXPLAIN on the SQL generated by a relation this way:
User.where(:id => 1).joins(:posts).explain
The result of that method call is a string that carefully imitates the output of database shells. For example, under MySQL you get something similar to
EXPLAIN for: SELECT `users`.* FROM `users` INNER JOIN `posts` ON `posts`.`user_id` = `users`.`id` WHERE `users`.`id` = 1
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
| 1 | SIMPLE | users | const | PRIMARY | PRIMARY | 4 | const | 1 | |
| 1 | SIMPLE | posts | ALL | NULL | NULL | NULL | NULL | 1 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
2 rows in set (0.00 sec)
and under PostgreSQL the same call yields something like
EXPLAIN for: SELECT "users".* FROM "users" INNER JOIN "posts" ON "posts"."user_id" = "users"."id" WHERE "users"."id" = 1
QUERY PLAN
------------------------------------------------------------------------------
Nested Loop Left Join (cost=0.00..37.24 rows=8 width=0)
Join Filter: (posts.user_id = users.id)
-> Index Scan using users_pkey on users (cost=0.00..8.27 rows=1 width=4)
Index Cond: (id = 1)
-> Seq Scan on posts (cost=0.00..28.88 rows=8 width=4)
Filter: (posts.user_id = 1)
(6 rows)
Please note that explain runs the query or queries and asks the
database for their respective query plan afterwards. This is because due to eager loading a relation may trigger several queries to fetch the records and their associations, and in such cases some queries need the result of
the previous ones.
If the relation triggers several queries the method still returns a single string with all the query plans. This is an output meant for human consumption so we preferred to present everything as a string in a format which is familiar right away rather than a structure.
Automatic EXPLAIN For Slow Queries
Rails 3.2 has the ability to help in detecting slow queries.
New applications get
config.active_record.auto_explain_threshold_in_seconds = 0.5
in config/environments/development.rb. Active Record monitors queries and if
they take more than that threshold their query plan will be logged using warn.
That works for anything running find_by_sql (which is almost everything, since
most of Active Record ends up calling that method). In the particular case of
relations, the threshold is compared against the total time needed to fetch the
records, not against the time taken by each individual query. Because
conceptually we are concerned with the cost of the call
User.where(:id => 1).joins(:posts).explain
rather than the cost of the different queries that call may trigger due to the implementation.
By default the threshold is nil in the test and production environments, which
means the feature is disabled.
The value of that parameter is nil also if the threshold is not set, so
existing applications will need to add it by hand if they migrate to 3.2 to be
able to enable automatic EXPLAIN.
Silencing Automatic EXPLAIN
With automatic EXPLAIN enabled, it could still be the case that some queries are just slow and you know they have to be. For example, a heavyweight report in the backoffice.
The macro silence_auto_explain allows you to avoid having EXPLAIN run
repeatedly in those areas of code:
ActiveRecord::Base.silence_auto_explain do
# no automatic EXPLAIN here
end
Interpreting Query Plans
The interpretation of the query plans is another topic, these are some pointers:
- SQLite: EXPLAIN QUERY PLAN
- MySQL: EXPLAIN Output Format
- PostgreSQL: Using EXPLAIN
Happy debugging!
more »
What's New in Edge Rails »
Created at: 13.10.2009 00:40, source: Riding Rails - home, tagged: Edge

So, Edge Rails is still chugging right along. There are new and interesting fixes, changes, and refactors going on all of the time. So, lets take a look at just a few that've gone in since the last post (it's been a while, I know, I'm sorry!).
ActionView and Helpers
XSS escaping is now enabled by default. This means that if you want to explicitly output HTML to your views, you'll probably have to mark it as html_safe! before sending it through.
<%= 'my <a href="http://www.rubyonrails.org">safe</a> string'.html_safe! %>
Many of the built-in helpers have been updated for this change and if you see an issues with the Rails helpers being incorrectly sanitized, you should create a new ticket.
distance_of_time_in_words has gained 'over', 'about', and 'almost' keywords, thanks to Jay Pignata and John Trupiano. This provides you with an improved level of granularity when approximating the amount time passed. So, instead of just "2 years ago", it can now also report "almost 2 years ago," "about 2 years ago," and "over 2 years ago," depending on the proximity to being exactly 2 years old.
assert_equal "almost 2 years", distance_of_time_in_words(from, to + 2.years - 3.months + 1.day)
assert_equal "about 2 years", distance_of_time_in_words(from, to + 2.years + 3.months - 1.day)
assert_equal "over 2 years", distance_of_time_in_words(from, to + 2.years + 3.months + 1.day)
assert_equal "over 2 years", distance_of_time_in_words(from, to + 2.years + 9.months - 1.day)
assert_equal "almost 3 years", distance_of_time_in_words(from, to + 2.years + 9.months + 1.day)
The HTML form helper, fields_for - generally used for nesting additional model forms - now allows for explicit collections to be used, thanks to Andrew France. So, instead of just including all of your blog.posts, you should have it only display your published blog.posts, for example. Or:
<% form_for @person, :url => { :action => "update" } do |person_form| %>
...
<% person_form.fields_for :projects, @active_projects do |project_fields| %>
Name: <%= project_fields.text_field :name %>
<% end %>
<% end %>
API Change for content_tag_for: The third argument - being the optional CSS prefix - will now also affect the generated CSS class. This prefix will now be appended to the generated element's CLASS attribute.
<%= content_tag_for(:li, @post, :published) %>
# => <li id="published_post_123" class="published_post">...</li>
ActiveResource and ActiveRecord
Taryn East has added update_attribute(s) methods to ActiveResource. These methods act very similarly to the ActiveRecord methods we already know and love.
Building or creating an object through a has_one association that contains conditionals will now automatically append those conditions to the newly created object, thanks to Luciano Panaro.
class Blog
has_author :commit_author, :class_name => 'Author', :conditions => {:name => "Luciano Panaro"}
end
@blog.build_commit_author
# => #<Author name: "Luciano Panaro" ... >
Pratik Naik added a new option to ActiveRecord's accepts_nested_attributes_for to :limit the number of records that are allowed to be processed. Also, while we're covering accepts_nested_attributes_for, José Valim as renamed the _delete option to _destroy to better follow what is actually occurring. A deprecation warning has been added to _delete, for the time being.
Jacob Burkhart updated the new autosave option in Rails 2.3 to allow for an :autosave => false, which will disallow saving of associated objects, even when they are new_record?s.
Some Internals
Previously, CDATA elements could be ignored when converting from XML to a Hash, so now, thanks to John Pignata, Hash#from_xml will now properly parse and include CDATA elements values.
Josh Peek has relocated global exception handling into ActionDispatch::Rescue. So, this is now being handled at the Rack middleware level.
And finally, Yehuda Katz and Carl Lerche began work on a Rails::Application object to better encapsulate some of the application start up and configuration details. Also, a good bit of initialization has now gone on to move into this new object.
Remember, if you prefer to have a shorter audio summary of some of this content and more, you should check out the Ruby5 podcast over at Envy Labs; it's released every Tuesday and Friday with the latest news in the Ruby and Rails community.
Photo: Clock Tower by Brian Taylor
more »
What's New in Edge Rails: The Security Edition »
Created at: 06.09.2009 20:07, source: Riding Rails - home, tagged: Edge

It's been a bit over two weeks since the last WNiER ("winner"?) post and in the time since our last visit, Ruby on Rails 2.3.4 was released to fix some reported security issues. It is important that you try to upgrade your applications as soon as possible, or even just apply the provided patches if a full upgrade isn't easily accomplished in your situation.
Along with this release, you're also going to see several bug fixes and enhancements to the Rails framework, coming from many contributors, that have been discussed here over the previous weeks and even a few that are mentioned just below.
Security updates
Michael Koziarski posted fixes (here and here) for cleaning and verifying multibyte (unicode) strings. The problem was reported by Brian Mastenbrook and Manfred Stienstra provided input for the fix. These changes should disallow malformed unicode strings from getting past the HTML escaping logic provided by the form helpers.
Coda Hale reported and also added a patch to Rails, fixing a timing attack vulnerability in ActiveSupport::MessageVerifier. Although not likely to be exploited in the wild, the vulnerability may allow an attacker to forge the signatures which encode your application's cookie store. If successfully broken, an attacker could modify their session objects without altering your application to the change.
There have been some issues reported around the Rails 2.3.4 release, specifically with regard to Ruby 1.9 support. While they have not all yet been fully substantiated, this certainly underscores the importance of having proper test coverage and both a staging and production environment for your applications.
Down to the metal
Yehuda Katz and Carl Lerche put in quite a bit of work around ActionController::Metal and Rack's Middleware, recently. ActionController::Metal now acts as a Rack middleware and at the same time, there is a new ActionController::Middleware class that operates as normal Rack middleware.
And, if that wasn't enough, Yehuda went on to add ActiveModel::Lint. ActiveModel::Lint allows you to determine whether or not an object is compliant with the ActiveModel API, via:
ActiveModel::Compliance.test(object)
The output is similar to a Test::Unit output and will indicate with which portions of the ActiveModel API the given object is - or more importantly is not - compliant.
If Metal is your thing, you may want to take a look at Yehuda Katz's recent blog post, How to Build Sinatra on Rails 3.
Pour some sugar on me
Quite a few changes, small and large, occurred around ActiveRecord and friends. Most of these cleaned up some existing functionality, either making it easier to use, perform more closely to what would be expected, or even adding some new features that will soon feel like old friends.
Taryn East added a little ActiveRecord-like love to ActiveResource. In this patch, ActiveResource received the familiar first, last, and all shortcut methods for wrapping the basic find method.
Proc and symbol support was added to the validates_numericality_of ActiveRecord validation, by Kane.
For those of you who use the :anchor option when generating URLs, you may notice that after this patch by Jeffrey Hardy, Rails will now execute the to_param method on the object provided as an :anchor.
@post = Post.first
@comment = Comment.first
post_url(@post, :anchor => @comment) # => http://www.example.com/posts/1#comment-1
Well, something similar to that, anyway. :) This updates the :anchor options to follow a similar functionality as the other options provided when generating URLs.
José Valim cleaned up some bits in the Rails scaffold. The generated new and edit views will now reference a new _form partial. This is a much DRYer way to go about it, and more closely follows what would likely happen if you were to code it yourself. Also, while he was there, he removed a bit of inline CSS (specifically, a green flash message), in favor of a CSS class and updating the default scaffold stylesheet.
And, probably the most interesting change in this group is the addition of a new ActivRecord#previous_changes method, by Scott Barr. previous_changes allows you to see what changed before the last save in your local ActiveRecord object instance. This is particularly useful when calling after_save methods which might need to know what exactly had changed. I'll let him give you a code sample:
person = Person.find_by_name('bob')
person.name = 'robert'
person.changes # => {'name' => ['bob, 'robert']}
person.save
person.changes # => {}
person.previous_changes # => {'name' => ['bob, 'robert']}
person.reload
person.previous_changes # => {}
Okay, let's do it your way
While a lot of us prefer US English, we (begrudgingly) recognize that we aren't always the center of the universe. As such, there are some more localization updates to report in Edge Rails:
Sven Fuchs added localization support to the ActiveRecord::RecordInvalid exception's error message. Then, Akira Matsuda followed Sven with support for localizing the SELECT tag helper's prompt text (the default being, "Please select").
Finally, this is certainly a welcome addition and potentially a major player in localization support within Rails: Antonio Tapiador del Dujo added a patch which allows Rails plugins to define and maintain their own locale files. All that is necessary for the plugin developer to do is to provide a config/locales/ directory within their plugin and then create their own .rb or .yml files (i.e. en.yml). That means that plugins can now be much more responsible for their own localization support and do not have to modify the application's locale files after installation.
Food for thought
Finally, just a small note that the default, preferred table collation for MySQL has been changed. Previously, Rails defaulted to utf8_general_ci when either the database or the table creation script did not dictate otherwise. Now, that has been changed to utf8_unicode_ci. Certainly worth a note with so many Rails applications using MySQL in their back-end.
Update: Set the attribution of previous_changes to Scott Barr. Sorry, Scott!
Photo: Security at the Hoover Dam by Alex E. Proimos
more »
Three reasons to love ActionController::Responder »
Created at: 31.08.2009 21:02, source: Riding Rails - home, tagged: Edge rails responder
A couple weeks ago, I wrote about the newly added ActionController::Responder which summarizes your application behavior for a specified format in just one place. For example, the default html behavior is written as:
class ActionController::Responder
def to_html
if get?
render
elsif has_errors?
render :action => (post? ? :new : :edit)
else
redirect_to resource
end
end
end
Here are three examples of the flexibility this new layer can provide.
1) HTTP Cache
A simple, but quite powerful use for responder is apply HTTP cache to all your resources easily. For simplicity, let's cache just get requests that are not handling a collection:
module CachedResponder
def to_html
if get? && resource.respond_to?(:updated_at)
return if controller.fresh_when(:last_modified => resource.updated_at.utc)
end
super
end
end
2) I18n flash messages
Is a common practice that all controllers, when the create, update and destroy actions are handled with success, a flash message is shown to the user. We could easily remove the flash messages from our controllers and let them be handled by the responder with the help of the I18n framework. And it’s quite straightforward to accomplish:
module FlashResponder
# If it's not a get request and the object has no errors, set the flash message
# according to the current action. If the controller is users/pictures, the
# flash message lookup for create is:
#
# flash.users.pictures.create
# flash.actions.create
#
def to_html
unless get? || has_errors?
namespace = controller.controller_path.split('/')
namespace << controller.action_name
flash[:success] = I18n.t(namespace.join("."), :scope => :flash,
:default => "actions.#{controller.action_name}", :resource => resource.class.human_name)
end
super
end
end
The first question then arises: what if I don’t want to add a flash message in an specific situation? This can be solved using options, since all options sent to respond_with are sent to the responder, we could use it in our favor as well:
class MyResponder < ActionController::Responder
def to_html
unless get? || has_errors? || options.delete(:flash) == false
namespace = controller.controller_path.split('/')
namespace << controller.action_name
flash[:success] = I18n.t(namespace.join("."), :scope => :flash,
:default => "actions.#{controller.action_name}", :resource => resource.class.human_name)
end
super
end
end
And we can invoke it as:
class PostsController < ApplicationController
def create
@post = Post.create(params[:post])
respond_with(@post, :flash => false)
end
end
3) Instant pagination
Some people already start a project with pagination from scratch, others add at some point. Nonetheless, pagination is more like a rule than a exception. Can that be handled by Rails 3? First, let’s check an index action with respond_with:
class PostsController < ApplicationController
def index
@posts = Post.all
respond_with(@posts)
end
end
Right now, when we call Post.all, it returns a collection of posts in an array, so the pagination should be done before the collection is retrieved. Thanks to Emilio and his work integrating ActiveRelation with ActiveRecord, Post.all will return an ActiveRecord::Relation that will be sent to the responder:
module PaginatedResponder
# Receives a relation and sets the pagination scope in the collection
# instance variable. For example, in PostsController it would
# set the @posts variable with Post.all.paginate(params[:page]).
def to_html
if get? && resource.is_a?(ActiveRecord::Relation)
paginated = resource.paginate(controller.params[:page])
controller.instance_variable_set("@#{controller.controller_name}", paginated)
end
super
end
end
However, the code above is definitely smelling. Set the paginated scope seems more to be a controller responsability. So we can rewrite as:
module PaginatedResponder
def to_html
if get? && resource.is_a?(ActiveRecord::Relation)
controller.paginated_scope(resource)
end
super
end
end
class ApplicationController < ActionController::Base
def paginated_scope(relation)
instance_variable_set "@#{controller_name}", relation.paginate(params[:page])
end
hide_action :paginated_scope
end
As previously, you could make use of some options to customize the default pagination behavior.
Wrapping up
All the examples above were contained in modules, that means that our actual responder has yet to be created:
class MyResponder < ActionController::Responder
include CachedResponder
include FlashResponder
include PaginatedResponder
end
To activate it, we just need to overwrite the responder method in our application controller:
class ApplicationController < ActionController::Base
def paginated_scope(relation)
instance_variable_set "@#{controller_name}", relation.paginate(params[:page])
end
hide_action :paginated_scope
protected
def responder
MyResponder
end
end
While those examples are simple, they show how you can dry up your code easily using Responder. And you? Already thought in an interesting use case for it?
more »
