问题描述
存储在 lib/tasks/items_spider.rake
中的简单 rake 任务在开发中运行良好.它所做的只是在 Item
模型上调用 spider!
.
My simple rake task, stored in lib/tasks/items_spider.rake
runs just fine in development. All it does is call spider!
on the Item
model.
namespace :items do
desc "Spider the web for data, hoorah"
task :spider => :environment do
Item.spider!
end
end
我将 :environment
任务作为依赖项,所以一切正常.但是,当我添加 RAILS_ENV=production
时,我在本地服务器和生产服务器上都遇到了错误:
I have the :environment
task as a dependency, so everything works just fine. However, when I add RAILS_ENV=production
, I hit errors, both on my local server and the production server:
$ 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 处于测试阶段时开始的.我该如何去调试这个问题?谢谢!
This just seems odd to me. Apparently the models have not been loaded correctly. I'm on Rails 3.0.3, though development on this app started back when Rails 3 was in beta. How can I go about debugging this issue? Thanks!
推荐答案
与在生产中运行应用程序相反,Rake 任务不急切加载整个代码库.您可以在源中看到它:
Contrary to running your application in production, a Rake task does not eager load your entire code base. You can see it in 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_task
是 false
,应用程序才会在生产中被预先加载.并且 $rails_rake_task
在 :environment
Rake 任务中设置为 true
.
So only if $rails_rake_task
is false
, will the application be eager-loaded in production. And $rails_rake_task
is set to true
in the :environment
Rake task.
最简单的解决方法是简单地require
您需要的模型.但是,如果您真的需要在 Rake 任务中加载所有应用程序,那么加载它非常简单:
The easiest workaround is to simply require
the model that you need. However, if you really need all of your application to be loaded in the Rake task, it is quite simple to load it:
Rails.application.eager_load!
所有这些都在开发中工作的原因是因为 Rails 在开发模式下自动加载您的模型.这也适用于 Rake 任务.
The reason all of this work in development is because Rails autoloads your models in development mode. This also works from within a Rake task.
这篇关于Rails 3 rake 任务在生产中找不到模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!