Rake DB Tasks Always Runs Twice in Development Environment
Recently, we set up a new Rails project (named as app
below), and our database.yml
is shown below, so you can see that it reads from environment variables to set database names and credentials accordingly:
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV['DATABASE_POOL'] %>
host: <%= ENV['DATABASE_HOST'] %>
database: <%= ENV['DATABASE_NAME'] %>
username: <%= ENV['DATABASE_USER'] %>
password: <%= ENV['DATABASE_PASSWORD'] %>
development:
<<: *default
test:
<<: *default
we noticed that rake DB tasks always run twice in development environment as shown below:
$ rake db:drop
Dropped database 'app_development'
Dropped database 'app_development'
$ rake db:create
Created database 'app_development'
app_development already exists
After I drill down the problem, I found that the problem is caused by a 'smart' feature in Rails. When running DB rake tasks, ActiveRecord checks the current environment, and if current environment is development, it runs the task in development database first and followed by test database (you can refer to method each_current_configuration
in lib/activerecord/tasks/database_tasks.rb
for more details).
Our database.yml
relies on environment variables to determine the target database. When a rake DB task is executed in development environment, the task will be run upon development database first, which is app_development
. Then, the task is run upon test database, which is app_development
again, because the environment variables for databases are the same. That is why the same task is run twice on development database.
To fix this, I simply hard code the database name for test environment in database.yml:
test:
<<: *default
database: knight_test