Solving Rake DB tasks with dotenv executed twice in dev environment
Have you ever ran into this?
Or perhaps an EnvironmentMismatchError
?
If you kept reading chances are you’re using dotenv and ran into the magical feature of Rake DB tasks being executed in both dev and test envs when invoked in dev env (see).
The issue, as explained on Zhu Wu’s blog, is that the smart environment change doesn’t take possible environment variable change into account and rather uses the DB config which was preloaded in dev env. E.g. if you have database: <%= ENV['DATABASE_NAME'] %>
in your DB config, the new value of that variable in test env will not be reloaded. I since created a detailed issue in Rails listing some further implications and an example project for reproducing the issue.
What’s the solution? There’s a couple.
The least intrusive is probably to use different env vars such as TEST_DATABASE_NAME
and DEV_DATABASE_NAME
in which case the tasks would work as expected. That’s clearly counter-intuitive though.
You could get rid of the double-execution by using custom DB tasks. You can write them yourself or use gems such as activerecord-migrations (referenced in this related issue).
Or finally, you could fix Rake DB tasks’ behaviour so that they work as expected: execute for both dev and test envs and properly initialize the environments. This is what I did in the gem dotenv_rails_db_tasks_fix. It monkey patches a method called each_current_configuration
in ActiveRecord::Tasks::DatabaseTasks
which is responsible for this whole mess (see). When switching environments it reloads env vars and DB config properly. Monkey pathing is discouraged but here I only do it in development environment so I consider this safe to use.
If you’re facing the same issue give these options a try and spare future developers the confusion that surrounds this whole topic.