45 votes

Comment puis-je forcer RAILS_ENV dans une tâche rake ?

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 je l'exécute, il ignore le RAILS_ENV que j'ai essayé de coder en dur. Comment puis-je faire en sorte que cette tâche fonctionne comme prévu ?

50voto

Michael Sofaer Points 2139

Pour cette tâche particulière, vous avez seulement besoin de changer la connexion à la base de données, donc comme Adam l'a souligné, 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, il est plus sûr de créer un nouveau processus rake :

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

19voto

yacc Points 406

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

11voto

Kris Points 3781

Une autre option consiste à vérifier l'env et à refuser de continuer :

unless Rails.env.development?
  puts "This task can only be run in development environment"
  exit
end

ou demander 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

7voto

Adam Byrtek Points 5791

La solution la plus propre et la plus simple serait de redéfinir RAILS_ENV (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 du code Rails utilise RAILS_ENV directement.

Cependant, comme Michael l'a souligné dans un commentaire à sa réponse, la commutation 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 version par défaut de l'application db:test tâches

ActiveRecord::Base.establish_connection(:test)

4voto

ealdent Points 2062

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 rake, mais si pour une raison quelconque ce n'est pas ce que vous voulez faire, vous pouvez faire ceci :

ENV["RAILS_ENV"] = 'test'
RAILS_ENV.replace('test') if defined?(RAILS_ENV)

load "#{RAILS_ROOT}/config/environment.rb"

Et ça devrait faire l'affaire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X