Question

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 :)

Was it helpful?

Solution

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.

OTHER TIPS

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).

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top