Hidden Secrets of the Rails Dev: Gotchas While Migrating from 2 to 3

Upon migrating from Rails 2 to 3, one might happen across some “gotchas”. I present a few such that you may heed caution.

ActiveSupport::Callbacks#run_callbacks

This method takes a &block parameter. In Rails 2, &block will run after each callback, and halt the chain if it returns false. In Rails 3, &block will run after the :before/:around callbacks and before the :after callbacks. More has changed about callbacks, so please read the docs.

Mail#header

ActionMailer in Rails 3 uses a different underlying library than 2: mail instead of tmail. Setting headers in the new library will accumulate headers rather than replacing them:

m['X-Something'] = 1
m['X-Something'] = 2
m.header['X-Something'] = 3

Now m has 3 values for the X-Something header: 1, 2 and 3.

ActiveRecord::Base#touch

In Rails 2, touch() ultimately calls save!() and runs through all the validation and callbacks. In Rails 3, touch() saves the record using update_all(), so no validations are performed and only the new after_touch() callback is run.

ActiveRecord#order

In Rails 2, queries are ordered like this:

User.first(:order => "name")

In Rails 3, AREL gives us a new method for queries called order(), but remember that it will accumulate order values instead of replacing them:

User.order("name").order("id").first
# ... ORDER BY name, id .... #

Remember to use reorder() to reset the value:

User.order("name").reorder("id")
# ... ORDER BY id ... #

Accent theme by Handsome Code


view archive



Ask me anything