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

问题描述 投票:0回答: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

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

ruby-on-rails rake rails-migrations
4个回答
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

参考资料:


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 do
块内)


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

0
投票

请关注https://sampatbadhe.medium.com/rake-task-invoke-or-execute-419cd689c3bd这对我来说效果很好。

本质上是运行

需要“耙子” MyRailsApp::Application.load_tasks

然后

Rake::Task['universe:world:shout'].invoke

将 MyRailsApp 替换为您的应用程序名称,并将 'universe:world:shout' 替换为您的 rake 任务名称

© www.soinside.com 2019 - 2024. All rights reserved.