Forum: Ruby on Rails Migrations, data loads and changes to the model

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
5d15c6821f3c3054c04b85471824ba7c?d=identicon&s=25 John Wells (Guest)
on 2006-02-24 19:17
(Received via mailing list)
Guys,

I've run across an interesting scenario with my migrations, and I hope
you might share some insight.

Let's say I have 3 migrations and two Models (Person and Car):
001_initial_schema.rb
002_data_load.rb
003_add_car_association.rb

The first creates the initial schema...the second loads default data
using model objects of Person to do so, and the third creates a new
table, "cars", and modifies the "persons" table to create a :has_one
relationship of Person[1]->[1]Car.

Let's also say I want all Persons to have at least one car, so I change
my Person model to have:

def after_initialize
  self.car = Car.new unless self.car
end

Now, what happens, is that when I issue a "rake migrate" on my intial
database
When I start from scratch (new database) and do a rake migrate, my data
load fails because it uses the model class Person, yet Person's code now
has an after_initialize that expects the Car association to be present.
Because Car isn't created until migration 003, I'm essentially up the
creek. rake throwns an InvalidStatement exception.

Has anyone found a decent way of handling these scenarios?

Thanks!
John
821395fe70906c8290df7f18ac4ac6cf?d=identicon&s=25 Rick Olson (Guest)
on 2006-02-24 19:38
(Received via mailing list)
> Thanks!
> John

I prefer to keep my migrations free of my models for this very reason.
 I'll create temp models if I need to do basic queries, however.

class MyMigration < Migration
  class Article < AR::Base
  end

  def self.up
  end

  def self.down
  end
end

This essentially makes the model's name MyMigration::Article, and
won't clash with your app's Article model or any other migrations'
Article models.

disclaimer:  I haven't *actually* tried this. However, I ran into this
issue on my Mephisto blogging tool and created temp models like
TempArticle.  Someone had a question on the Rails-Core ML and led me
to this idea.  I'll try it next.

http://techno-weenie.net/svn/projects/mephisto/tru...


--
Rick Olson
http://techno-weenie.net
17acfbd3a05cfb59e0543235cc0a813b?d=identicon&s=25 Joshua Susser (Guest)
on 2006-02-24 19:39
> I've run across an interesting scenario with my migrations, and I hope
> you might share some insight.
> ...
> Has anyone found a decent way of handling these scenarios?

http://scottstuff.net/blog/articles/2005/10/31/mig...
http://rails.techno-weenie.net/tip/2006/2/23/safel...
Ad7805c9fcc1f13efc6ed11251a6c4d2?d=identicon&s=25 Alex Young (Guest)
on 2006-02-25 11:42
(Received via mailing list)
Rick Olson wrote:
>   def self.down
>   end
> end
>
> This essentially makes the model's name MyMigration::Article, and
> won't clash with your app's Article model or any other migrations'
> Article models.
>
> disclaimer:  I haven't *actually* tried this.
Having googled a bit, and seen your conversation on the rails-core list,
I did try it.  It works.  Very nicely :-)

It's a situation that I'm surprised doesn't come up more often.  Changes
to models breaking old migrations must be quite a common occurrence,
both because of lifecycle callbacks and because of relationship changes.
  The rules of thumb I've come up with are:
- Always use local models in migrations (as above).  An alternative
would be a patch to AR that exposed create_without_callbacks, but that
was more complex than I wanted to get in to, and wouldn't cover
everything.
- Never rely on dynamic associations, always use foo[:bar_id] = qux[:id]
rather than foo.bar = qux.

I've found that following those rules allows changes to model code while
also letting your app bootstrap itself in a single rake migrate pass.
This topic is locked and can not be replied to.