【问题标题】:Execute a Rake task from within migration?从迁移中执行 Rake 任务?
【发布时间】:2011-02-07 14:18:32
【问题描述】:

我有一个将配置数据从文件加载到数据库中的 Rake 任务,是否有正确的 ruby​​/rails 方法在向上迁移时调用它?

我的目标是同步我的团队数据库配置,无需广播即可运行任务 lalala

  def self.up
    change_table :fis_situacao_fiscal do |t|
      t.remove :mostrar_endereco
      t.rename :serie, :modelo 
    end

    Faturamento::Cfop.destroy_all()
    #perform rake here !
  end

更新 我现在的工作方式和工作方式:

system('rake sistema:load_data file=faturamento/cfop')

这是 @Ryan Bigg 的建议,这是个例外:

Rake::Task['rake sistema:load_data file=faturamento/cfop'].invoke()

.

==  AlterSituacaoFiscalModeloEndereco: migrating ====================
-- change_table(:fis_situacao_fiscal)
   -> 0.0014s

rake aborted!
An error has occurred, this and all later migrations canceled:

Don't know how to build task 'rake sistema:load_data file=faturamento/cfop'

哪里出错了?

【问题讨论】:

  • 你为什么要传入“rake”这个词?不带它试试。它知道这是一个简单的任务。
  • @Fabiano:更新了答案。

标签: ruby-on-rails ruby migration


【解决方案1】:

是的,有办法做到这一点:

Rake::Task['your_task'].invoke

更新

不要将 rake 放在方括号内,只需将任务的 名称。你应该在运行这个时设置一个 ENV 变量:

在控制台中

FILE=somefile.text rake db:sistema:load_data

单独调用

FILE=somefile.text rake some:other:task:that:calls:it

这将在您的任务中作为ENV['file'] 提供

【讨论】:

  • 我对您的回答进行了更新,很高兴您能提供更多帮助
  • 如果任务在命名空间中怎么办?我有一个可以用rake semi:seed[89] 运行的种子系统(将运行以89_ 开头的.rb 文件),但我不能用Rake::Task['semi:seed[89]'] 调用它你知道如何调用种子吗?迁移文件中的任务?
  • 我的错,我只需要在调用中传递 89 参数:Rake::Task['semi:seed'].invoke('89') 工作正常
  • 有其他人收到You have 1 pending migrations:。它不允许在迁移过程中运行另一个 rake 任务。
  • 如果您不知道您的任务名称,请运行 rake -T -A 以获取完整列表
【解决方案2】:

请注意,如果您使用 'system' 调用 Rake 任务,则需要在之后检查进程状态并在 Rake 任务失败时引发异常。否则即使 Rake 任务失败,迁移也会成功。

您可以像这样检查进程状态:

if !($?.success?)
  raise "Rake task failed"
end

调用 rake 任务是一个更好的选择 - 如果 Rake 任务失败,它将导致迁移失败。

【讨论】:

    【解决方案3】:

    您可以使用 Rake::Task['namespace:task'].invokeRake::Task['namespace:task'].execute 在已加载的 Rails 环境中执行 rake 任务。

    您可以将数据传递给invokeexecute 方法内的任务。示例:

    Rake::Task['namespace:task'].invoke(paramValue)
    

    这个参数可以在 rake 任务中处理如下:

    namespace :namespace do
      desc "Example description."
      task :task, [:param] => :environment do |t, args|
        puts args[:param]
        ...
      end
    end
    

    这可以在控制台上执行为:

    bundle exec rake namespace:task[paramValue]
    

    更多信息:https://medium.com/@sampatbadhe/rake-task-invoke-or-execute-419cd689c3bd

    【讨论】:

      【解决方案4】:

      This decision 更适合,恕我直言。

      在你的情况下,它会是这样的:

      backup_env = ENV.slice('file') if ENV.key?('file')
      ENV['file'] = 'faturamento/cfop'
      Rake::Task['sistema:load_data'].invoke
      ENV.delete 'file'
      ENV.merge!(backup_env) if backup_env
      

      【讨论】:

        猜你喜欢
        • 2021-08-28
        • 1970-01-01
        • 2011-12-01
        • 2012-10-03
        • 2013-06-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多