The Spaghetti Refactory Established 2015

Migrating data in Rails using Rails migrations

Put this one in the “should’ve been obvious” column…

For an embarassingly long while, when I had a feature ready for deploy that required production data be modified for a whole bunch of records – for example, downcasing all name attributes – I would write a one-off rake task to update those records, then delete that task.

Not only is this bad code since it doesn’t keep a record of what happened, it’s also tedious because it’s an extra step that must be taken by whoever deploys the code.

Luckily there’s a better way - just put the updating login in a migration!

Example:

class DowncaseName < ActiveRecord::Migration
def up
User.where.not(name: nil).find_each do |user|
user.update!(name: user.name.downcase)
end
end
end

This example isn’t great because 1. there’s almost certainly a way to do this with pure SQL without instantiating every user record, and 2. it’s not reversible. But since I’m lazy and since it illustrates the point of the post, I’m leaving it.