ruby-on-rails - schedule cron rails
La tarea Rails 3 rake no puede encontrar modelo en producción (2)
Mi sencilla tarea de rake, almacenada en lib/tasks/items_spider.rake
funciona perfectamente en desarrollo. ¡Todo lo que hace es llamar a la spider!
en el modelo del Item
.
namespace :items do
desc "Spider the web for data, hoorah"
task :spider => :environment do
Item.spider!
end
end
Tengo la tarea :environment
como una dependencia, así que todo funciona bien. Sin embargo, cuando agrego RAILS_ENV=production
, toco errores, tanto en mi servidor local como en el servidor de producción:
$ 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...]
Esto me parece extraño. Aparentemente los modelos no se han cargado correctamente. Estoy en Rails 3.0.3, aunque el desarrollo de esta aplicación comenzó cuando Rails 3 estaba en beta. ¿Cómo puedo seguir depurando este problema? ¡Gracias!
Contrariamente a ejecutar su aplicación en producción, una tarea de Rake no ansia cargar toda su base de código. Puedes verlo en la fuente :
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
Entonces, solo si $rails_rake_task
es false
, la aplicación estará $rails_rake_task
cargada en producción. Y $rails_rake_task
se establece en true
en :environment
tarea del :environment
Rake.
La solución más fácil es simplemente require
el modelo que necesita. Sin embargo, si realmente necesita que toda su aplicación se cargue en la tarea Rake, es bastante simple cargarla:
Rails.application.eager_load!
La razón de todo este trabajo en desarrollo es porque Rails autocarga sus modelos en modo de desarrollo. Esto también funciona desde dentro de una tarea de Rake.
En su entorno / production.rb, debe agregar lo siguiente:
config.dependency_loading = true if $rails_rake_task
Me solucionó el problema.
(Nota: esto se debe agregar DESPUÉS de la llamada config.threadsafe!)