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 Reply