【问题标题】:Rails 3 rake task can't find model in productionRails 3 rake 任务在生产中找不到模型
【发布时间】:2011-05-17 01:27:12
【问题描述】:

我的简单 rake 任务,存储在 lib/tasks/items_spider.rake 中,在开发中运行良好。它所做的只是在Item 模型上调用spider!

namespace :items do
  desc "Spider the web for data, hoorah"
  task :spider => :environment do
    Item.spider!
  end
end

我有 :environment 任务作为依赖项,所以一切正常。但是,当我添加 RAILS_ENV=production 时,我在本地服务器和生产服务器上都遇到了错误:

$ rake items:spider RAILS_ENV=production --trace
(in /home/matchu/Websites/my-rails-app)
** Invoke items:spider (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute items:spider
rake aborted!
uninitialized constant Object::Item
/home/matchu/.rvm/gems/ruby-1.9.2-preview3@rails3/gems/rake-0.8.7/lib/rake.rb:2503:in `const_missing'
/home/matchu/.rvm/gems/ruby-1.9.2-preview3@rails3/gems/rspec-core-2.0.0.beta.22/lib/rspec/core/backward_compatibility.rb:20:in `const_missing'
/home/matchu/.rvm/gems/ruby-1.9.2-preview3@rails3/gems/rspec-expectations-2.0.0.beta.22/lib/rspec/expectations/backward_compatibility.rb:6:in `const_missing'
/home/matchu/Websites/openneo-impress-items/lib/tasks/items_spider.rake:4:in `block (2 levels) in <top (required)>'
/home/matchu/.rvm/gems/ruby-1.9.2-preview3@rails3/gems/rake-0.8.7/lib/rake.rb:636:in `call'
[...trace of how rake gets to my task...]

这对我来说似乎很奇怪。显然模型没有正确加载。我在 Rails 3.0.3 上,虽然这个应用程序的开发可以追溯到 Rails 3 处于测试阶段时。我该如何调试这个问题?谢谢!

【问题讨论】:

  • 这里有点意思,但是您是否尝试过将 RAILS_ENV 声明移动到命令的开头?
  • Item 模型保存在哪里?常去的地方?
  • @Ryan:嗯。 app/models/item.rb
  • 现在去睡觉了;不知何故,我现在才想到用其他模型进行测试。明天试试 :) 谢谢!
  • this answer

标签: ruby-on-rails ruby-on-rails-3 rake


【解决方案1】:

与在生产环境中运行您的应用程序相反,Rake 任务急切地加载您的整个代码库。你可以在the source看到它:

module Rails
  class Application
    module Finisher
      # ...
      initializer :eager_load! do
        if config.cache_classes && !$rails_rake_task
          ActiveSupport.run_load_hooks(:before_eager_load, self)
          eager_load!
        end
      end
      # ...
    end
  end
end

所以只有如果$rails_rake_taskfalse,应用程序会在生产环境中被预先加载。并且$rails_rake_task:environment Rake 任务中设置为true

最简单的解决方法是简单地require 您需要的模型。但是,如果您真的需要在 Rake 任务中加载所有应用程序,那么加载它非常简单:

Rails.application.eager_load!

所有这些在开发中工作的原因是 Rails 在开发模式下自动加载您的模型。这也适用于 Rake 任务。

【讨论】:

  • 做了更多的研究,结果发现这与我的应用程序在生产中被标记为线程安全有关,而我实际上并没有提到这一点。我将更多地研究如何解决这个确切的问题。谢谢!
  • $rails_rake_task 在最新版本的 rake 或 rails 中不再定义,但您仍然可以在 Rakefile 中手动设置 $rails_rake_task = true
  • Rails.application.eager_load!不适用于我的 rake 任务。它说 application_controller.rb 未找到。我跟踪跟踪,在 active_support/dependencies.rb#search_for_file autoload_paths 内为空。然而,在我的 Application.rb 文件中,我明确地将控制器添加到 autoload_paths。发生了什么事?
  • 这解决了我在生产环境中运行 rake 任务时收到NameError: uninitialized constant ... 的问题(开发工作正常)。添加Rails.application.eager_load! 为我解决了这个问题。
【解决方案2】:

在您的 environment/production.rb 中,您应该添加以下内容:

config.dependency_loading = true if $rails_rake_task

它为我解决了问题。

(注意:这应该在 config.threadsafe! 调用之后添加)

【讨论】:

  • 为什么还需要这个?这看起来像一个错误,不是吗?如果它加载 :environment,它也应该加载模型
  • rails 4 中有没有更好的方法?
  • $rails_rake_task 在最新版本的 rake 或 rails 中不再定义,但您仍然可以在 Rakefile 中手动设置 $rails_rake_task = true
【解决方案3】:

刚刚找到另一个:我在 windows 上开发,部署到 Heroku。 Web 应用程序和 Rails 控制台运行良好,但 rake 任务甚至直接 require 都无法加载模型。原来我心不在焉地将模型文件创建为Model.rb 而不是model.rb - 取决于系统区分大小写。

【讨论】:

    【解决方案4】:

    我在 Rails 6.0.3.2 中也发生了同样的事情。

    我试图配置 rake 文件 task :foo do ... end. 而它应该是 task foo: :environment do ... end

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-13
      • 2011-12-12
      • 1970-01-01
      • 1970-01-01
      • 2011-07-13
      • 1970-01-01
      • 2011-04-11
      • 1970-01-01
      相关资源
      最近更新 更多