J'ai cette petite tâche de râteau:
namespace :db do
namespace :test do
task :reset do
ENV['Rails_ENV'] = "test"
Rake::Task['db:drop'].invoke
Rake::Task['db:create'].invoke
Rake::Task['db:migrate'].invoke
end
end
end
Maintenant, lorsque j'exécuterai, il ignorera le Rails_ENV que j'ai essayé de coder en dur. Comment faire pour que cette tâche fonctionne comme prévu
Pour cette tâche particulière, il vous suffit de modifier la connexion DB, donc comme l'a souligné Adam, vous pouvez le faire:
namespace :db do
namespace :test do
task :reset do
ActiveRecord::Base.establish_connection('test')
Rake::Task['db:drop'].invoke
Rake::Task['db:create'].invoke
Rake::Task['db:migrate'].invoke
ActiveRecord::Base.establish_connection(ENV['Rails_ENV']) #Make sure you don't have side-effects!
end
end
end
Si votre tâche est plus compliquée et que vous avez besoin d'autres aspects d'ENV, vous générez le plus sûr un nouveau processus de râteau:
namespace :db do
namespace :test do
task :reset do
system("rake db:drop Rails_ENV=test")
system("rake db:create Rails_ENV=test")
system("rake db:migrate Rails_ENV=test")
end
end
end
ou
namespace :db do
namespace :test do
task :reset do
if (ENV['Rails_ENV'] == "test")
Rake::Task['db:drop'].invoke
Rake::Task['db:create'].invoke
Rake::Task['db:migrate'].invoke
else
system("rake db:test:reset Rails_ENV=test")
end
end
end
end
Dans Rails 3, vous devrez utiliser
Rails.env = "test"
Rake::Task["db:drop"].invoke
au lieu de
Rails_ENV = "test"
Rake::Task["db:drop"].invoke
Une autre option est de vérifier l'env et de refuser de continuer:
unless Rails.env.development?
puts "This task can only be run in development environment"
exit
end
ou demandez s'ils veulent vraiment continuer:
unless Rails.env.development?
puts "You are using #{Rails.env} environment, are you sure? y/n"
continue = STDIN.gets.chomp
exit unless continue == 'y'
end
La solution la plus propre et la plus simple serait de redéfinir Rails_ENV
(ne pas ENV['Rails_ENV']
)
namespace :db do
namespace :test do
task :reset do
Rails_ENV = "test"
Rake::Task['db:drop'].invoke
Rake::Task['db:create'].invoke
Rake::Task['db:migrate'].invoke
end
end
end
Pendant le processus de démarrage d'une application Rails Rails_ENV est initialisé comme suit
Rails_ENV = (ENV['Rails_ENV'] || 'development').dup unless defined?(Rails_ENV)
Le reste de Rails utilise Rails_ENV
directement.
Cependant, comme Michael l'a souligné dans un commentaire à sa réponse, le changement de Rails_ENV
à la volée peut être risqué. Une autre approche serait de changer la connexion à la base de données, cette solution est en fait utilisée par la valeur par défaut db:test
Tâches
ActiveRecord::Base.establish_connection(:test)
La meilleure façon est bien sûr de spécifier l'environnement à partir de la ligne de commande lorsque vous exécutez la tâche de râteau, mais si pour une raison quelconque ce n'est pas ce que vous voulez faire, vous pouvez le faire:
ENV["Rails_ENV"] = 'test'
Rails_ENV.replace('test') if defined?(Rails_ENV)
load "#{Rails_ROOT}/config/environment.rb"
Et cela devrait faire l'affaire.
Il y a du code étrange dans database_tasks.rb
:
def each_current_configuration(environment)
environments = [environment]
environments << 'test' if environment == 'development'
configurations = ActiveRecord::Base.configurations.values_at(*environments)
configurations.compact.each do |configuration|
yield configuration unless configuration['database'].blank?
end
end
Il ajoute toujours test
si env est development
. J'ai résolu le cas de vouloir effectuer une tâche db:rebuild
Personnalisée pour development
et test
simultanées en exécutant development
en premier et test
en second . De plus, avant d'exécuter les tâches, j'appelle ma méthode set_env
Qui s'assure de définir ActiveRecord::Tasks::DatabaseTasks.env
, Sans cela, les connexions à la base de données ne semblent pas être traitées discrètement pour les environnements comme prévu. J'ai essayé toutes les autres sortes de déconnexion, etc., mais cela a fonctionné sans autre code.
def set_env(env)
Rails.env = env.to_s
ENV['Rails_ENV'] = env.to_s
ActiveRecord::Tasks::DatabaseTasks.env = env.to_s
end