4

我想使用迁移运行 rake 任务,因为我们希望当用户运行时rails db:migrate,该任务将通过迁移运行。

我的 rake 任务是:

namespace :task_for_log do

  desc "This task set by default as current date for those logs where log_date is nil"
  task set_by_default_date_of_log: :environment do
    Log.where("log_date IS NULL").each do |log|
      log.update_attributes(log_date: log.created_at.to_date)
    end
  end

end

请指导执行此任务的迁移是什么,这里有什么人可以挽救我的生命吗?

4

3 回答 3

7

迁移实际上只是遵循约定的 Ruby 文件,所以如果你想在其中运行 rake 任务,你可以调用 Rake 类。

class ExampleMigration < ActiveRecord::Migration[5.0]
  def change
    Rake::Task['task_for_log'].invoke
  end
end

但是,迁移文件应该专门用于处理数据库模式。我会重新考虑您如何解决问题以获得更好的解决方案。例如,您可以运行更新日志属性的 SQL 语句,而不是调用 rake 任务。

class ExampleMigration < ActiveRecord::Migration[5.0]
  def change
    execute <<-SQL
      UPDATE logs SET log_date = created_at WHERE log_date IS NULL
    SQL
  end
end

参考:

于 2018-12-03T20:42:13.643 回答
3

如果你想在自动运行后运行你的任务,db:migrate可以使用enhance.

Rake::Task['db:migrate'].enhance do
  # This task runs after every time you run `db:migrate`
  Rake::Task['task_for_log:set_by_default_date_of_log'].invoke
end

对于 Rails 应用程序,您可以将其放在lib/tasks文件夹内的任何位置或将您的任务内联(在.enhance do块内)

于 2018-12-03T21:43:57.027 回答
1

你可以去@joseph 提到更好的解决方案!或者为它创建自定义任务。

耙:

rake cm:set_by_default_date_of_log

任务:

#lib/tasks/cm.rake
#custom_migration
namespace :cm do
  desc "This task set by default as current date for those logs where log_date is nil"
  task set_by_default_date_of_log: ['db:migrate'] do
    Log.where("log_date IS NULL").each do |log|
      log.update_attributes(log_date: log.created_at.to_date)
    end
  end
end
于 2018-12-03T21:00:45.570 回答