rake test fails - pending migrations

After running 'down' some migrations using 'rake db:migrate:down', I am unable to performs any tests. The message received is:

You have 3 pending migrations: 1. blah 2. blahblah 3. blahblahblah Run "rake db:migrate" to update your database then try again.

How can I remove (undo) migrations and run tests? Interestingly, 'similar actions' are working on a different machine. I remember having the same problem and it disappeared after I experimented few things with rake:db:migrate. Is there any procedure for removing migrations?

Thanks, Shantanu.

That's an unusual question. The reason you have tests is to verify your code actually does what you think it's doing. If you migrate down, you add and/or remove model attributes, which (hopefully) your code depends on. And your tests should fail if you change that. That is, if your code doesn't break just trying to run the tests.

Are your trying to run a prior version of your app? If so, you should use your revision control system to pull down an older copy of the code and db:reset.

HTH

Well, I need to remove some database tables from my application. So I am using rake db:migrate:down to undo/remove migrations. Also, I have changed (added/removed/modified) the code in model, view, controller, and tests to make these changes. Now I need to run tests in order to check everything is working.

I can pull out an old copy from revision control system. But, what if migrations that need to be removed are not the latest ones. Lets assume that there are 30 migrations. - migration # 15 and 17 - are related to adding new tables - migration # 22 and 25 - add column to above tables.

So I need to remove/undo migrations 15, 17, 22, and 25. I need other migrations as they are not related to these tables. What should I do in such situation?

I did db:migrate:down for above migrations and also made necessary changes in the code and now trying to run tests. Am I following wrong approach?

Thanks, Shantanu.

James Mitchell wrote:

Just remove the migration files themselves or make new migration files to remove the columns/tables.

Bobnation wrote:

Just remove the migration files themselves or make new migration files to remove the columns/tables.

If your project is not yet deployed (which I suspect it is not!).

I'm hoping the same. :wink:

I see. Ok, I see a couple of options here. Some of which have been suggested already.

1. Rip out (svn remove) the migrations you don't want. Reset the db. 2. Add new migrations to add/fix/remove the changes. 3. db:migrate down to the lowest possible version, comment out the the guts of the migrations you don't want. Then migrate back up. 4. Something entirely different that I can't think of right now:)

Which approach you should take depends on a couple of factors ... such as ... whether the app is in production yet, how much code and tests are affected, how true to the "rails way" you want to stay ... things like that.

Good luck with it.

Thanks for the help.

But then what is the purpose of db:migrate:down (and self.down method in migration file)? The method self.down does roll back any changes if needed, but its effects are not reflected in other areas such as 'rake test'.

I am probably going to do 'rake db:migrate:down' and then 'svn remove' for the particular migration file.

Thanks, Shantanu.

James Mitchell wrote:

Shantanu Pavgi wrote:

Thanks for the help.

But then what is the purpose of db:migrate:down (and self.down method in migration file)? The method self.down does roll back any changes if needed, but its effects are not reflected in other areas such as 'rake test'.

Migrations really shouldn't be thought of as "choose 4 items from part A of the menu".

If you need to make adjustments to your schema, you either rollback to a previous version of the schema earlier than what you want to undo and edit those migrations (each self.down should undo its self.up), or you create new migrations to remove what you don't want/need anymore (the self.down should put back what self.up removes).

The strength of the serial migrations is that you can migrate to the state of the schema at any point in time.

Riddle me this Batman:

If you undo just migrations 15, 17, 22, 25, and later add a new migration 33, what do you expect would happen when you rake db:migrate again?

I suspect that your pending migrations are migration files (like 017_add_x.rb) that aren't referenced in the schema_migrations table.

Shantanu Pavgi wrote:

But then what is the purpose of db:migrate:down (and self.down method in migration file)?

On a deployed database, the only direction should be up. If you deploy a new version, and encounter an emergency, the cap rollback feature cannot roll your database back. If the current code no longer likes the database, you could then use db:migrate:down, iff it is fully tested, and it won't erase any live data.

However, once you deploy, if you rethink a feature, and want less database fields, you should write a progressive migration that removes those fields in its .up method. Its .down method, if any, should put the fields back in.

Because you should not write proactive code into a .down method without immediately testing it, you generally should not write anything in a .down method when you create a new migration. Do not, for example, write a .down method because you think you must (or because an Official Style Guideline told you to) and then not test it. A colleague might run it, thinking it's tested, and get a nasty surprise. Worse, that could be you!

The major benefit of the .down method derives from a problem with unit tests and their fixtures. Unit tests should cover every line of your Rails project - /except/ the lines in your historical migrations! At migration time, your tests might dislike the new version. You can build a .down method, then fix the tests while alternately calling down and up on the migration.

Thank you very much for your inputs...