2009-07-07 7 views
43

mam ten mały zadanie Zgrabiarka:Jak wymusić RAILS_ENV w zadaniu prowizji?

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 

Teraz, kiedy mogę wykonać, będzie ignorować RAILS_ENV starałem się twardej kodu. Jak wykonać to zadanie zgodnie z oczekiwaniami?

Odpowiedz

48

Dla tego konkretnego zadania, trzeba tylko zmienić połączenie DB, tak jak Adam zauważył, można to zrobić:

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 

Jeśli zadanie jest bardziej skomplikowane i trzeba inne aspekty ENV jesteś najbezpieczniejszym tarła nowego procesu Zgrabiarka:

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 

lub

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 
+1

Tak, to wygląda trochę mniej hackowato niż przygniatając z RAILS_ENV –

+2

Dla mnie wywoływanie dodatkowych procesów Rake wygląda dużo * więcej * hacky. –

+2

To lepsze rozwiązanie niż niszczenie zadań w środowisku w niszczycielski sposób. Jeśli zrobisz to w ten sposób, możesz użyć go jako zależności w innym zadaniu, nie powodując całkowitej katastrofy. Chcesz uruchomić zadanie rake w trybie testowym? Uruchom zadanie w trybie testowym. Próbuje sfałszować tryb testowy, a oni prawdopodobnie zmieniają wszystko z powrotem w tryb, w którym faktycznie jesteś, a potem jest szkicowy. –

4

Najlepszym sposobem jest oczywiście określenie środowiska z linii poleceń po uruchomieniu zadania rake, ale jeśli z jakiegoś powodu nie jest to, co chcesz zrobić, możesz zrobić to:

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

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

To powinno załatwić sprawę.

+0

Być może po prostu być w stanie wymagać '„config/environment'' zamiast przeładowywania go. – ealdent

+0

Co za hack, działa jak mistrz. –

+0

wydaje się pracować dla zadania prowizji bez potrzeby lub obciążenia ... –

6

najczystszym i rozwiązanie najprostsze będzie do ponownego RAILS_ENV (nie 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 

Podczas rozruchu z aplikacji RAILS_ENV prowadnic jest inicjowany w następujący

RAILS_ENV = (ENV['RAILS_ENV'] || 'development').dup unless defined?(RAILS_ENV) 

Reszta kodu Szyny wykorzystuje RAILS_ENV bezpośrednio.

Jednak, jak zauważył Michael w komentarzu do swojej odpowiedzi, zmiana w locie RAILS_ENV może być ryzykowna. Innym rozwiązaniem byłoby, aby przełączyć połączenie z bazą danych, rozwiązanie to jest w rzeczywistości wykorzystywane przez domyślnie db:test zadania

ActiveRecord::Base.establish_connection(:test) 
17

W Rails 3, będziesz musiał użyć

Rails.env = "test" 
Rake::Task["db:drop"].invoke 

zamiast

RAILS_ENV = "test" 
Rake::Task["db:drop"].invoke 
9

Inną opcją jest sprawdzenie env i odmowa kontynuowania:

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

lub zapytać, czy naprawdę chcą, aby kontynuować:

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 
3

Jest jakiś dziwny kod w 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 

To zawsze dodaje test jeśli env jest development. Rozwiązałem przypadek wykonania niestandardowego zadania db:rebuild dla jednoczesnego development i test, uruchamiając najpierw development i test sekundę.Ponadto przed uruchomieniem zadań wywoływana jest moja metoda set_env, która zapewnia ustawienie ActiveRecord::Tasks::DatabaseTasks.env, bez tego połączenia z bazą danych nie wydają się dyskretnie obsługiwane w środowiskach zgodnie z oczekiwaniami. Próbowałem wszystkich innych rodzajów rozłączania itp., Ale działało to bez dalszego kodu.

def set_env(env) 
    Rails.env = env.to_s 
    ENV['RAILS_ENV'] = env.to_s 
    ActiveRecord::Tasks::DatabaseTasks.env = env.to_s 
end 

Here is a gist of my full db.rake file with simultaneous multi-environment db:rebuild and db:truncate

+0

nie działa w szynach 4 do tej pory –

+0

Pracuje dla nas w szynach 4, ponieważ został wprowadzony i nadal działa do dziś. – kross

+0

Dzięki. ok, przyjrzę się teraz twojemu sedno. –