我有这个小耙子任务:
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。 如何使这项工作按预期方式工作
对于这个特殊的任务,你只需要改变数据库连接,从而亚当指出的那样,你可以这样做:
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
在Rails 3,你将不得不使用
Rails.env = "test"
Rake::Task["db:drop"].invoke
代替
RAILS_ENV = "test"
Rake::Task["db:drop"].invoke
另一种方法是检查env和拒绝继续:
unless Rails.env.development?
puts "This task can only be run in development environment"
exit
end
或问,如果他们真的想继续:
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
最清洁和最简单的解决办法是重新定义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应用程序RAILS_ENV的引导过程如下初始化
RAILS_ENV = (ENV['RAILS_ENV'] || 'development').dup unless defined?(RAILS_ENV)
的Rails代码的其余部分使用RAILS_ENV
直接。
然而,正如迈克尔在他的回答评论所指出的那样,开关RAILS_ENV
的飞行是有风险的。 另一种方法是将切换数据库连接,这一解决方案实际上是在使用默认db:test
任务
ActiveRecord::Base.establish_connection(:test)
当然,最好的办法是从指定当您运行rake任务的命令行环境,但如果由于某种原因,你想做的事,这不是,你可以这样做:
ENV["RAILS_ENV"] = 'test'
RAILS_ENV.replace('test') if defined?(RAILS_ENV)
load "#{RAILS_ROOT}/config/environment.rb"
这应该做的伎俩。
有一些奇怪的代码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
它总是添加test
,如果ENV是development
。 我解决了想要做一个自定义的情况下db:rebuild
的任务,同时development
和test
运行development
第一,并test
第二。 此外,在运行任务之前,我打电话给我的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
这里是我的全部的要点db.rake
与同时多环境文件db:rebuild
和db:truncate