2009-07-07 14 views
43

मेरे पास यह छोटा रेक कार्य है:मैं एक रेक कार्य में RAILS_ENV को कैसे मजबूर करूं?

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 

अब, जब मैं निष्पादित करता हूं, तो यह RAILS_ENV को अनदेखा कर देगा, मैंने हार्ड-कोड की कोशिश की। मैं इस कार्य को अपेक्षित

के रूप में कैसे काम करूं?

उत्तर

48

इस विशेष कार्य के लिए, आप केवल, डीबी कनेक्शन बदलने की जरूरत है ताकि के रूप में एडम ने कहा, आप यह कर सकते हैं:

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 

अपने कार्य को और अधिक जटिल है, और आप ENV के अन्य पहलुओं की जरूरत है

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 

या

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

हाँ यह RAILS_ENV –

+2

के साथ घूमने से थोड़ा कम हैकी दिखता है मेरे लिए अतिरिक्त रेक प्रक्रियाओं का आह्वान करने के लिए * अधिक * हैकी दिखता है। –

+2

पर्यावरण के साथ विनाशकारी तरीके से अपने कार्य गड़बड़ होने से बेहतर है। यदि आप इसे इस तरह करते हैं तो आप कुल आपदा के बिना किसी अन्य कार्य में निर्भरता के रूप में इसका उपयोग कर सकते हैं। परीक्षण मोड में एक रेक कार्य चलाने के लिए चाहते हैं? कार्य मोड में कार्य चलाएं। फर्जी टेस्ट मोड की कोशिश कर रहे हैं, और संभवतः वे बाद में जो कुछ भी मोड में हैं, उसे स्केची है। –

4

का सबसे अच्छा तरीका यह है कि जब आप रेक कार्य चलाते हैं तो कमांड लाइन से पर्यावरण निर्दिष्ट करना है, लेकिन अगर किसी कारण से आप ऐसा नहीं करना चाहते हैं, तो आप कर सकते हैं यह:

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

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

और यह चाल चलाना चाहिए।

+0

तुम बस ' 'config/environment'' बजाय इसे फिर से लोड करने की आवश्यकता होती है करने में सक्षम हो सकता है। – ealdent

+0

क्या एक हैक, एक चैंप की तरह काम करता है। –

+0

ऐसा लगता है कि यह आवश्यक या लोड किए बिना रेक कार्य के लिए काम कर रहा है ... –

6

साफ:, आप एक नया रेक प्रक्रिया को उत्पन्न करने के सबसे सुरक्षित हैं और आसान समाधान फिर से परिभाषित करने RAILS_ENV (नहीं 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 

एक रेल आवेदन RAILS_ENV की बूट प्रक्रिया के दौरान आरंभ नहीं हो जाता के रूप में रेल कोड के बाकी RAILS_ENV सीधे का उपयोग करता

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

इस प्रकार होगा।

हालांकि, जैसा कि माइकल ने अपने उत्तर पर एक टिप्पणी में बताया है, फ्लाई पर RAILS_ENV स्विचिंग जोखिम भरा हो सकता है। एक और दृष्टिकोण डेटाबेस कनेक्शन स्विच करने के लिए हो सकता है, इस समाधान वास्तव में डिफ़ॉल्ट रूप से db:test कार्यों

ActiveRecord::Base.establish_connection(:test) 
17

प्रयोग किया जाता है रेल 3 में, आप

Rails.env = "test" 
Rake::Task["db:drop"].invoke 
बजाय

का उपयोग करना होगा
RAILS_ENV = "test" 
Rake::Task["db:drop"].invoke 
9

एक और विकल्प env की जांच करना और जारी रखने से इनकार करना है:

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

या पूछते हैं कि वे वास्तव में जारी रखना चाहते हैं:

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 

यह हमेशा test कहते हैं अगर env development है:

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

वहाँ database_tasks.rb में कुछ अजीब कोड है। मैंने development और test सेकेंड चलाकर एक साथ और test के लिए एक कस्टम db:rebuild कार्य करने के मामले को हल करने का मामला हल किया।इसके अलावा, कार्यों को चलाने से पहले, मैं अपनी set_env विधि को कॉल करता हूं जो ActiveRecord::Tasks::DatabaseTasks.env को सेट करने के लिए सुनिश्चित करता है, इसके बिना डेटाबेस कनेक्शन अपेक्षाकृत वातावरण के लिए विघटित रूप से संभाला नहीं लगता है। मैंने अन्य सभी प्रकार के डिस्कनेक्ट इत्यादि की कोशिश की, लेकिन यह बिना किसी कोड के काम किया।

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

रेल 4 में काम नहीं करता है –

+0

यह रेलवे 4 में हमारे लिए काम कर रहा है क्योंकि यह पेश किया गया था और अभी भी काम करता है। – kross

+0

धन्यवाद। ठीक है, मैं अब तुम्हारी जिंदगी को देख रहा हूँ। –

संबंधित मुद्दे