Migrations headache

This time it was migrations crash course….

Recently I had to change run-n-share database structure and remove some models. I needed to find easy way to do changes in DB and make data transformation. Of course I started doing it with migrations.

Quite successfully. With one exception.

Somewhere in migration I wrote following code:

Owner.find(:all).each {|o|
   begin
     r = Route.find(o[:route_id])
   rescue
     puts "#{o.route_id} not found in routes table"
     next
   end
[some operations on o and r]
}

Trouble is that no operation after begin/rescue is run – every iteration through Owners raises ‘undefined method find’. Most strange is Route class (I have AR model route!):

rake aborted!
undefined method `find' for 
#<ActiveRecord::ConnectionAdapters::MysqlAdapter:0x8d9c2c4>

I know about Safely using models – in my case this is not useful, since I need access to real model properties to make data transition. Using dumb model stub would give me only access to methods inherited from ActiveRecord::Base, and this is not enough for me.

Well, I have started digging and at the end I’ve put in migration following code:

 def self.up
    puts ActiveRecord::Base::Route.superclass
    puts ActiveRecord::Base::Owner.superclass
    puts "Surprised?"
 end

And ran migration. Results were:

ActiveRecord::Migration
ActiveRecord::Base
Surprised?

Well I’m surprised. Is this some special case with Route symbol? Like other issues I found during my short way with RoR:
https://nhw.pl/wp/2007/01/02/another-dumb-ror-restriction/
https://nhw.pl/wp/2006/05/30/dont-use-sessions-table-in-rails/

As a quick solution I have moved all data transformation to separate script run by ./script/runner and I break migrations flow raising exception to give chance run script in right moment. It is ugly hack, but it works…

If this is issue with some names clash (like with send action or sessions table) can somebody propose general solution? I don’t know Ruby and Rails enough to thought about feasible solution…

Join the Conversation

5 Comments

  1. Hi! I’ve got the same problem!

    I don’t understand why you raise a exception in order to run a script with “script/runner”, you cannot call “system” method directly?

    Thanks!

  2. Well it was ugly hack. I have not tested fully this external script, so I wanted to be sure, that migrations stops in right time, I will have time to do operations, MAKE SURE all data is OK and go further.

    Running it in external command via system does not leave time to do manual data check.

  3. I know this is pretty old but i ran into the same problem today. Do you have a migration named XXX_route.rb? This migation has a corresponding route class that is conflicting with your model class in the migration.

    Let me know if this works

  4. Well indeed I have one called just 003_route.rb. It could be a reason ;) since it begins with:

    class Route < ActiveRecord::Migration
    

    Now it makes sense why Route does not have find method. However, it should not have impact on

    puts ActiveRecord::Base::Route.superclass
    

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.