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
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...]
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!
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
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.
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!
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.
In your environment/production.rb, you should add the following:
config.dependency_loading = true if $rails_rake_task
It solved the problem for me.
(Note: this should be added AFTER the config.threadsafe! call)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With