Wednesday, April 28, 2010

Adding Rails Counter Cache - Two Stage Release

I recently added a counter cache to an existing has_many/belongs_to association. I am using a hosted Rails application (heroku)

I went through all the steps:

1) create a migration adding a table_name_count column to the counting table, and initializing table_name_count to the the proper value

2) add :counter_cache => true to my :belongs_to association

3) make use of .size instead of .count for counting the associations

4) write proper unit tests to verify the counter is updated

It all worked - until deployment. The migration did not fail, but my counter fields remained 0.

Odd, it all worked locally. Must be an issue with my host - NOT.

Here is the skinny:

Specifying :counter_cache => true makes the counter field read only. Updating it does not cause an error, the model can still be saved, and modified? returns true. However, the field does not get saved - it is a transient change.

It wasn't a problem locally, because I had done these in the proper order. With git as my interface to heroku, all these steps were effectively compressed into one.

To fix this, I had to deploy this change in two stages:

A) Migration, initializing the value
B) Model and other code updates.

And it worked.

No comments: