---
title: Gotchas When Upgrading to Rails 2.1
teaser:
tags: web,rails
author: Chad Pytel
published_on: 2008-06-19
---

We've upgraded several Rails 2.0 application to Rails 2.1 now, and we've
compiled a list of little things to keep in mind as you upgrade.  Hopefully this
list will help you avoid banging your head against a wall.

## Partial Updates

The updated\_at and updated\_on columns are NOT automatically updated on a #save
on an AR object in Rails 2.1, unless another column has also changed.  In each
of the cases where we were relying on this behavior, we were using it to detect
in a general way that something had changed with the model (without introducing
a dependency on `acts_as_modified`).  Because Rails 2.1 has dirty attribute
checking, these methods were able to be refactored using this new functionality.

## Will Paginate

Older versions of [will_paginate](http://github.com/mislav/will\_paginate) are
broken on 2.1 (stack level too deep errors), to resolve, install the latest
version of `will_paginate` like this:

    sudo gem install mislav-will_paginate -s http://gems.github.com

Then put require `will_paginate` in an initializer or in environment.rb (you
need to have added vendor/gems to load path already to do that).

This newer `will_paginate` has changed the `#page_count` method to be
`#total_pages` instead, so you'll have to keep that in mind.  Which means, some
of the `will_paginate` view helpers changed as well – if you’ve monkey patched
them (you haven’t unless you’re me!) look for changes there too!

Finally, [Squirrel’s](https://github.com/thoughtbot/squirrel)
WillPagination module provides a `#page_count` method.  To get a `#total_pages`
from squirrel results, we temporarily monkey patched Squirrel by adding a
lib/extensions/squirrel.rb which was just…

```ruby
module Squirrel
  module WillPagination
    alias_method :total_pages, :page_count
  end
end
```

We'll need to update Squirrel soon to have this built in so that its compatible
with the latest version of `will_paginate`.

## Shoulda

Make sure you've upgraded [Shoulda](https://github.com/thoughtbot/shoulda)
if you get errors about not being able to find fixture methods and/or assert,
especially if these errors appear in setup blocks.

## HAML

Unfortunately, [haml](http://haml.hamptoncatlin.com/-1.8.x) isn’t Rails 2.1
compatible.  To fix this, upgrade to haml-2.0.

## Reply-to in mailers

If you have the following hack in your mailer, just remove it. Rails 2.1 does it
for you:

```ruby
def reply_to(str)
  @headers["Reply-To"] = str
end
```

## Changes in Active Record Attribute Filtering

ActiveRecord::Base#attributes does not allow filtering anymore (it does not
accept :only, for example). You must do the filtering manually, with something
like this:

    def json_attributes_for(model, *attrs)
      attrs = [attrs].flatten.map(&:to_s)
      model.attributes.delete_if{|k,v| !attrs.include?(k) }.to_json
    end

Called like so: `json_attributes_for(page, :id, :keyword)`

## Changes in Template Rendering

Now in Rails 2.1, if you both foo.rhtml and foo.rxml exist and you aren't
explicitly specifying one or the other, Rails will render with foo.rxml.
Renaming foo.rhtml to foo.html.erb fixes this, but in Rails 2.0, this was ok.

## Relationship Optimized Eager Loading

In order to deal with the [1+n](https://railscasts.com/episodes/22) query
problem, Active Record has changed how it does eager loading.  Now, it will
optimize out :includes on finders when they are not being used.  When they are
not being used is the key here.  Active Record is supposed to noticed when there
are additional conditions on the find that rely on the included table, and not
leave it out.

However, on an association like this:

```ruby
has_many :active_sites,
  :through => :clients,
  :source => :sites,
  :include => :domains,
  :conditions => 'domains.id IS NOT NULL'
```

Active Record leave out the domains table, even though it shouldn't.  We fixed
this by changing `active_sites` to just a normal method, as the bug doesn’t seem
to happen in find, like this:

```ruby
def active_sites
  sites.find :all, :include => [:domains], :conditions => 'domains.id IS NOT NULL'
end
```

## has\_finder

`has_finder` has been integrated into Rails 2.1 as `named_scope`, so you don't
need it anymore.  However, you also shouldn't keep it around.  For example,
has\_finder-1.0.5 was giving us stack trace too deep exceptions when traversing
a `has_many :through` association. Removing it in favor of `named_scope` fixed
that issue.

## In Conclusion

Those are the things that we've found that we feel might be helpful to other
people out there.  For the most part, upgrading to Rails 2.1 is a a
straightforward process, and we're quickly upgrading most of our apps.

Have you upgraded to 2.1 and run into anything that other people might hit?  If
so, feel free to add your gotchas to the comments.
