Db:drop, create & migrate behavior with RAILS_ENV=development

I have noticed that when RAILS_ENV=development (which is the default when in development)

rails db:drop and rails db:create tasks run on both the development, and test databases (drop, and create databases for both test and development environment).

You can see this documented here.

rails:db:migrate however, only runs on the development database, so test environment is excluded.

Is there any reason why these commands interact with RAILS_ENV differently? If not, I would love to see db:migrate, migrate the test database as well, to save the step of running another command :slight_smile:

12 Likes

I agree - this distinction has always been really unclear - I find myself assuming one case or another, and I’m usually wrong.

1 Like

Thank you for bring this up.

The test schema is automatically maintained by the Rails test framework (bin/rails test command), so you don’t need to call db:migrate on the test database. I don’t know if it is also automatically maintained by RSpec.

1 Like

Additionally in Docker environments where the database reasonably lives on mysql or some other non-localhost hostname the “This tool only operates on local databases” renders the database tools pretty well useless, or at least unreliable and unpredictable.

1 Like

A vote from Twitter:

Referring to:

https://github.com/rails/rails/issues/27299

4 Likes

RSpec doesn’t do this by default, so for anyone using it just add this to your spec/rails_helper.rb

ActiveRecord::Migration.maintain_test_schema!
3 Likes

maintain_test_schema! also is part of rspec-rails’s default rails_helper now, which is great.

2 Likes

I would prefer when all* the rails db:... commands would run by default only for one environment.

The default is development, so I would expect them to only create or drop or migrate my development database.

It is not only confusing that some commands change development and test while others don’t, but also does make working with some mixed local dev and/vs Docker setups weird.

My suggestion to ease the pain to keep the test db updated, would be to have this as an opt-in option (for the legacy workflow ;-)) or to ensure that rails db:test:prepare does all the necessary step.


  • = the one exception might be rails db:setup which is supposed to setup a whole dev environment.
2 Likes

Does this mean what I was asking for in the OP is now done?

Not quite! This isn’t baked into Rails now or anything. I meant that if you run bin/rails generate rspec:install, then the generated rails_helper.rb includes code that should run the equivalent of db:test:prepare at the start of every test run.

2 Likes