【问题标题】:Do something in a rake task before Rails models are loaded在加载 Rails 模型之前在 rake 任务中做一些事情
【发布时间】:2017-07-19 16:39:51
【问题描述】:

我有一个适用于模型的 rake 任务。但我需要告诉模型它们是从 Rake 中使用的,而不是在应用程序中使用的。我最好的想法是在运行 rake 任务之前在命令行上设置一个环境变量,但这需要团队中的每个人都记住使用环境变量。具体来说,我有一个 if 语句可以在运行 rake 任务时跳过加载 Delayed::Jobhandle_asynchronously

class Thing < ActiveRecord::Base
  searchable do
    string :title
    text :title, :content
  end
  handle_asynchronously unless ENV['MIGRATINGDATA']
end

当我们运行迁移任务时,我们会这样做:

MIGRATINGDATA=true bundle exec rake project:migrate_data

我想摆脱对命令行进行特殊添加的需要。我们的迁移代码加载了一个虚假的 Sunspot 实例以在迁移数据时关闭索引。

【问题讨论】:

    标签: ruby-on-rails ruby rake delayed-job sunspot


    【解决方案1】:

    只需在您的 Rakefile 顶部设置一些内容:

    ENV['HELLO_RAKE'] = true
    
    require_relative 'config/application'
    
    Rails.application.load_tasks
    

    如果你愿意,你可以设置一个常量,而不是使用ENV,例如HELLO_RAKE = true 然后检查defined?(HELLO_RAKE)

    另一种方法是只检查正在运行的程序是否为rake

    handle_asynchronously unless File.basename($0) == "rake"
    

    这两种方法的一个缺点是它们将在您使用 Rake 的任何时候生效,其中包括与迁移无关的其他 Rake 任务。

    【讨论】:

    • 这看起来可行!我试了一下,似乎按预期工作。我使用了 ENV,它在模型之前被加载和设置。谢谢!
    【解决方案2】:

    如果您的模型关心您是否在 rake 任务中使用它们,那么您做错了什么。相反,您可以将参数添加到某些方法,例如。在您的特定用例中,您可以改为立即运行作业。将其放在 rake 任务的开头:

    Delayed::Worker.delay_jobs = false
    

    【讨论】:

    • 关于模型的好点不应该关心它们是否处于耙子中。通常我会同意,但在这种情况下,我们正在迁移数据并且不需要运行这一特定行,因为我们将在迁移后处理它。这只会执行一次。成功部署后,此代码将被删除。但是,在我们实际部署之前,我们需要在开发中使用它。 delayed_jobs = false 没有帮助。我对替代品持开放态度。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多