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 »
What's New in Edge Rails: No REST for the weary »
Created at: 20.08.2009 18:01, source: Riding Rails - home, tagged: Edge

This week's post will be rather short and sweet. The notable commits of the week seemed to revolve mainly around refactoring and even slightly altering the way some of the bits work. Lets get into it:
I'm Partially impressed
Yehuda Katz was able to simplify some of the partial rendering logic this week, although in doing so seems to very slightly alter the call methodology. So now, when calling the local object from within a partial, you will have the choice of using either the partial name (i.e. "_post.html.erb" would be "post") as the reference for the local object, or you may make it unique by passing in the :as option (i.e. render :partial => "post", :as => "poster_boy" would be "poster_boy"). You no longer have the option of using both interchangeably from within your partial. Also, the :object option for render :partial has been removed, in favor of the methods previously mentioned.
We won't Accept it
The way in which Rails handles incoming Accept headers has been updated. This was primarily due to the fact that web browsers do not always seem to know what they want ... let alone are able to consistently articulate it. So, Accept headers are now only used for XHR requests or single item headers - meaning they're not requesting everything. If that fails, we fall back to using the params[:format].
It's also worth noting that requests to an action in which you've only declared an XML template will no longer be automatically rendered for an HTML request (browser request). This had previously worked, not necessarily by design, but because most browsers send a catch-all Accept header ("*/*"). So, if you want to serve XML directly to a browser, be sure to provide the :xml format or explicitly specify the XML template (render "template.xml").
I'll tell you where you can go...
Josh Peek finally removed the deprecated "best fit" route generation support. Mostly for the sake of speed and maintainability, the new router will simply use the first matching route in your routes.rb file, rather than the "best" match. If you've been working at all on the Edge and haven't noticed the deprecation warnings, then this probably won't affect you.
Oh, so that's why!
Jay Pignata provided a patch this week to help out all of you RESTful API developers. Previously, when a client sent invalid XML or JSON to your server, Rails would 500 with an oh-so-descriptive /!\ FAILSAFE /!\ error in your logs. This wasn't much help if you were trying to debug it. So, with this patch, you'll now get to look at the raw data that was posted to your server in your logs.
Speaking of Resources
Finally, a few updates went into ActiveResource this week which will make it a lot more familiar to those of us who are more comfortable with ActiveRecord. Validation support has been added, which will allow you to both validate your resources locally - before transmission - and remotely. ActiveResource no longer throws a ResourceNotFound error when you attempt to find a set of undefined resources [Resource.find(:all)]. Instead, ActiveResource is reverting to the more ActiveRecord-like empty set/nil response. And last, but not least, resource.save! will now raise a ResourceInvalid unless the resource is, actually .. well .. valid?
That's it for this week's update on Edge Rails. I hope that you've enjoyed it.
Photo: Hood River Sunset by Bernt Rostad
more »
