Rails Migrations: Managing The Data Like A Boss

Ale Fernandes Antunes

Developer for Neon Roots

Some days ago, I needed to create a new field for one of the models for a project I’m currently working on. Up to this point there had been nothing new in the rails world. However, the field I was needing was an order field, as instances of the model were returned ordered by creation date and the requirement that I was assigned would be able to order it regardless of the date, using the new field.

So, what is better in this scenario? Should I create a migration file for the field and a seed file for fixing the data in production (populating the new field considering creation date for the objects)? Or was it better to have a db script file/stored procedure for this purpose? After researching a little I’ve found the right tool for the job: migration_data gem.

How I Chose To Implement The Migration_Data Gem

This cool gem (migration_data github page) allows you to create migration files containing the well-known change methods and data methods as well. The purpose is for you to include a data section on the same migration file just for fixing the data, and as the other collaborators (or the deploy engine) has to run the migrations, you can be a 100% sure that the data will be fixed.

So let me show you how my migration file looked like:

class AddOrderToMockModel < ActiveRecord::Migration
  def change
    add_column :mock_models, :order, :integer, index: true
  end

  def data
   i = 1
   MockModel.all.order(created_at: :asc).each do |mock_model|
     mock_model.order = i
     mock_model.save
     i += 1
   end
  end
end

So as you can see, the file has the old change method but has a data section as well. It basically iterates over all the elements and populates the new field considering creation_date to assign the new value.

Another cool feature about this gem is that it gives you the possibility of writing tests for your migration files. Let me show you what my test for this migration looked like:

require 'spec_helper'
require 'migration_data/testing'
require_migration 'add_order_to_mock_model'

describe AddOrderToMockModel do
  describe '#data' do
    it 'works' do
      expect { described_class.new.data }.to_not 
        raise_exception
    end
  end
end

 

I’ve just added the necessary code to check for the correctness of the syntax on the data part in the migration file, but you can play around here and provide a complete set of tests if your migration needs it.

Final thoughts

When you are working with collaborators on a project, chances are you have to change models overtime.

Rails has methods for updating the data in a db; using seeds is one of them. The problem with this method is that seed file tends to get real messy and big overtime, and there is a chance that the seed task won’t get called.

I’ve found this gem to be the most effective way to deal with this kind of situation. It is very clear:  you have the file for modifying the table and below the data correction script. You are also able to use ruby syntax and you can write test for them as well. Basically, it lets you manage the data like a boss.

Sorry, no posts matched your criteria.