如何在Rails中使用迁移运行Rake任务?

4
我想在Rails中使用迁移运行Rake任务。每次执行rails db:migrate命令时,任务将通过迁移运行。
当前的Rake任务如下所示。
namespace :task_for_log do
    desc 'This task sets current date as a default for 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

我该如何使用迁移文件来运行该任务?


如果您的意图是使用迁移,为什么要在这里使用Rake任务?这些“更新”本身可以成为迁移的一部分。 - kasperite
因为这是我的客户的要求,所以我需要翻译这个内容。 - Rana. Amir
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

参考资料:


我正在使用PGSql,您能否根据此进行转换? - Rana. Amir
当然,我已经更新了它。我不知道你的“logs”表格叫什么,所以你可能需要相应地进行更改。这是我使用的参考链接:https://www.oreilly.com/library/view/practical-postgresql/9781449309770/ch04s05.html - Joseph Cho
运行时,只需从SQL命令中删除表格即可。谢谢,它正常工作。 - Rana. Amir
@JosephCho 给合适的人点赞。 :) - ray

4
如果你想要在自动运行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块内)


1
你可以像 @joseph 提到的那样使用更好的解决方案!或者为此创建自定义任务。

rake:

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

但是我的客户认为这种方法不好,因为我们必须通过手动命令来运行此任务,因此我们必须创建一个迁移文件,在其中运行此任务。 - Rana. Amir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接