Can someone please explain what
ActiveRecord::Base.connection.migration_context.last_stored_environment
means semantically?
Due to it’s naming I would expect that it would just contain the last stored environment — which could be different if someone switches the environment.
So if I did something in development
before and switched to test
environment, I would expect, that ActiveRecord::Base.connection.migration_context.last_stored_environment
returns 'development'
and ActiveRecord::Base.connection.migration_context.current_environment
returns test
.
But my understanding regarding this, is either wrong or my understanding regarding ActiveRecord::Tasks::DatabaseTasks.check_protected_environments!
is wrong.
Because check_protected_environments!
does the following
current = ActiveRecord::Base.connection.migration_context.current_environment
stored = ActiveRecord::Base.connection.migration_context.last_stored_environment
…
if ActiveRecord::Base.connection.migration_context.protected_environment?
raise ActiveRecord::ProtectedEnvironmentError.new(stored) # "You are attempting to run a destructive action against your '#{env}' database…"
end
So when current
is 'development'
but stored
is 'production'
it will raise with the message “You are attempting to run a destructive action against your ‘production’ database…” although the current environment (where we expect to run those queries against) is 'development'
.
So I’m clearly miss out something.
Some Background
What I’m trying to do is, dropping the postgresql database from a rake task and making sure before that there’s no open connection left:
# terminate all open DB connections
db_config = ActiveRecord::Base.connection_config
query = <<-SQL.strip.gsub(/\s*\n\s*/m, ' ')
SELECT pg_terminate_backend(pg_stat_activity.procpid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = '#{db_config[:database]}'
AND pg_stat_activity.procpid <> pg_backend_pid();
SQL
ActiveRecord::Base.connection.execute query
# dropping the database
Rake::Task['db:drop'].invoke
So I would expect that everything runs fine on my development machine without providing any environment variables like RAILS_ENV
or DISABLE_DATABASE_ENVIRONMENT_CHECK
because I should stay in development
environment anyway. But somehow I’m running into the ActiveRecord::ProtectedEnvironmentError
because last_stored_environment
is set to production
and the whole thing doesn’t make any sense to me.
PS: I’m very open if someone knows a better way to kill all open connections beforehand but I also want to know why the source is as it is.