ruby-on-rails 我如何覆盖/增强Rails默认的db:. Rake任务来做一些不同的事情?

a2mppw5e  于 5个月前  发布在  Ruby
关注(0)|答案(1)|浏览(72)

我正在迁移一个Rails应用程序,该应用程序使用PostgreSQL模式(search_path)使用多租户,而不是使用多数据库/水平共享中内置的Rails。在这个过程中,我需要能够覆盖db:..任务,如rails db:migraterails db:migrate:rollback等。
我试过:

#config/initializers/migrations.rb
module Migrations
  module DatabaseTasks
    def migrate(*)
      ["a", "b", "c"] do |schema|
        ActiveRecord::Base.connection.schema_search_path=schema
        puts "------------- migrating: #{schema} --------------"
        super
      end
    end
  end
end

ActiveSupport.on_load(:active_record) do
  ActiveRecord::Tasks::DatabaseTasks.singleton_class.prepend(Migrations::DatabaseTasks)
end

字符串
这对于rails db:migrate非常有效,但是对于rails db:migrate:downrails db:rollback不起作用,因为它们不调用ActiveRecord::Tasks::DatabaseTasks.migrate请参阅:https://github.com/rails/rails/blob/bc2f390f7d2a96030532f41c08205f159e05af10/activerecord/lib/active_record/railties/databases.rake#L260
我也尝试了自己的rake任务:

# tasks/my_custom_db_tasks.rake
namespace :db do
  task migrate: :environment do |_task, _args|

    # Get a reference to the original db:migrate task
    original_migrate_task = Rake::Task['db:migrate']

    # Run the original migration task the specified number of times
    ["a", "b", "c"] do |schema|
      ActiveRecord::Base.connection.schema_search_path=schema
      puts "----------  migrating: #{schema} --------------"
      original_migrate_task.invoke
      original_migrate_task.reenable
    end
  end
end


但是对所有任务都这样做很麻烦,而且它也不起作用,因为我试图覆盖任务定义的方式似乎有问题。

**我的问题是:**什么是最好的方法来一般挂钩到db:...测试和运行原始/”super“任务多次?

tzcvj98z

tzcvj98z1#

可以“增强”rake任务
我以前用过的一个例子是:

Rake::Task['db:migrate'].enhance ['db:my_task_before_migrate']
Rake::Task['db:rollback'].enhance ['db:my_task_before_rollback']

Rake::Task['db:migrate'].enhance do
  Rake::Task['db:my_task_after_migrate'].invoke
end

Rake::Task['db:rollback'].enhance do
  Rake::Task['db:my_task_after_rollback'].invoke
end

字符串
注意这里作为参数传递和作为块传递的区别。当作为参数传递时,传递的任务在你增强的任务之前运行。
当它作为一个块传递时,被调用的任务在被增强的任务之后运行。

相关问题