【发布时间】:2022-01-23 17:51:45
【问题描述】:
我正在使用我的 Ruby on Rails (3) 应用程序设置第二个数据库,因此我想创建一个 rake 任务来创建第二个开发数据库。我正在尝试覆盖 rake db:create 任务,以便它完成我需要的所有数据库创建。但是,似乎我找不到合适的方法来执行此任务。我尝试了几种方法 - 从 URL 建立到数据库的连接:
# remove db:create from the list of rake tasks in order to override it
db_create = Rake.application.instance_variable_get('@tasks').delete('db:create')
namespace :db do
task :create do
if Rails.env == "development"
# database.yml contains an entry for secondary_development, this works, as confirmed from rails console
ActiveRecord::Base.establish_connection "postgresql://localhost/secondary_development"
Rake::Task["db:create"].invoke # this does nothing
end
# invoke original db_create task - this works
db_create.invoke
end
end
另一种方法是:
# remove db:create from the list of rake tasks in order to override it
db_create = Rake.application.instance_variable_get('@tasks').delete('db:create')
namespace :db do
task :create do
if Rails.env == "development"
Rails.env = "secondary_development"
Rake::Task["db:create"].invoke
end
# invoke original db_create task - this doesn't work like this
db_create.invoke
end
end
这一次只有secondary_developmentdb:create 可以正常工作,并且可以根据需要创建数据库,但不再使用这种方法创建development 数据库。
根据我在其他地方找到的一个答案,我认为重新启用该任务是必要的,但这并没有改变这里的任何东西,而且似乎不是问题。
最后,一种行之有效的方法是:
# remove db:create from the list of rake tasks in order to override it
db_create = Rake.application.instance_variable_get('@tasks').delete('db:create')
namespace :db do
task :create do
if Rails.env == "development"
system("rake db:create RAILS_ENV=secondary_development")
end
db_create.invoke
end
end
这里唯一的问题是,因为 rake 任务是通过 system 运行的,Rails 应用程序必须在执行之前加载,所以我实际上是为了运行任务而完全加载应用程序两次 - 这将是当我将测试数据库添加到组合中时 3 次。
所以,实际的问题:
是否可以在指定环境下以编程方式运行Rake::Task["..."]?
为什么ActiveRecord::Base.establish_connection 在创建数据库时不能这样工作?从 Rails 控制台运行它时我取得了成功。
【问题讨论】:
标签: ruby-on-rails ruby ruby-on-rails-3 rake