Migrations with advanced data operations

I was quite busy last week. I’m developing major upgrade to Run-N-Share, my daily job brings me some normal Cisco (eeek it is no more fun and exciting thing for me) related work, and I was testing updated geocoding services for Poland area from Google (in polish).

Making major changes to RNS means migrations heavy usage. It turns out I had some misconceptions about them, but now with new experience I can use it more efficiently.

So few words for You, maybe it will save Your time.


First, when using any non-trivial migrations (trivial are simple add_column, create_table and nothing more) always construct dumb placeholder for ActiveRecord classes. Like:

class PointOrder < ActiveRecord::Migration
  class Point < ActiveRecord::Base
  end
  class Route < ActiveRecord::Base
  end
  def self.up
     #CODE
  end
 

This provides You all-methods-You-would-normally-expect. Like Route.find. Without this Route.superclass would be ActiveRecord::Migration instead of ActiveRecord::Base, and for this find is no method. But this advice is very popular so I probably does say nothing new.

More useful can be to say You need to put Your relations in dumb models, to use associations. Migration code from above, which should iterate through all routes and update all points related with route now looks like that:

class PointOrder < ActiveRecord::Migration
  class Point < ActiveRecord::Base
    belongs_to :route
  end
  class Route < ActiveRecord::Base
    has_many :points
  end
  def self.up
     #CODE
  end
 

With this add-on You can use:

    Route.find(:all).each { |r|
      r.points.each { |p| 
         #some stuff
      }
    }

And last, but not least: if some stuff means You operate on fields created in this migration, You have to say Rails things have changed with: Point.reset_column_information (in case fields for class Point were added earlier in this migration). Without this, Rails will use cached model without new fields.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.