views:

385

answers:

3

I have a sequence of migrations in a rails app which includes the following steps:

  1. Create basic version of the 'user' model
  2. Create an instance of this model - there needs to be at least one initial user in my system so that you can log in and start using it
  3. Update the 'user' model to add a new field / column.

Now I'm using "validates_inclusion_of" on this new field/column. This worked fine on my initial development machine, which already had a database with these migrations applied. However, if I go to a fresh machine and run all the migrations, step 2 fails, because validates_inclusion_of fails, because the field from migration 3 hasn't been added to the model class yet.

As a workaround, I can comment out the "validates_..." line, run the migrations, and uncomment it, but that's not nice.

Better would be to re-order my migrations so the user creation (step 2) comes last, after all columns have been added.

I'm a rails newbie though, so I thought I'd ask what the preferred way to handle this situation is :)

+4  A: 

The easiest way to avoid this issue is to use rake db:schema:load on the second machine, instead of db:migrate. D:S:L uses schema.rb to load the most current version of your schema, as opposed to migrating it up form scratch.

If you run into this issue when deploying to a production machine (where preserving data is important), you'll probably have to consolidate your migrations into a single file without conflicts.

Ben Scofield
+3  A: 

You can declare a class with the same name inside the migration, it will override your app/models one:

class YourMigration < ActiveRecord::Migration

  class User < ActiveRecord::Base; end

  def self.up
    # User.create(:name => 'admin')
  end

end

Unfortunately, your IDE may try to autocomplete based on this class (Netbeans does) and you can't use your model logic in there (except if you duplicate it).

BiHi
A: 

I'm having to do this right now. Building upon BiHi's advice, I'm loading the model manually then redefining methods where I need to.

load(File.join(RAILS_ROOT,"app/models/user.rb"))
class User < ActiveRecord::Base
  def before_validation; nil; end # clear out the breaking before_validation
  def column1; "hello"; end       # satisfy validates_inclusion_of :column1
end
dznqbit