Задача Rails 3 rake не может найти модель в производстве
Моя простая задача rake, хранящаяся в lib/tasks/items_spider.rake
, отлично работает в разработке. Все, что он делает, это вызов spider!
в модели Item
.
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/[email protected]/gems/rake-0.8.7/lib/rake.rb:2503:in `const_missing'
/home/matchu/.rvm/gems/[email protected]/gems/rspec-core-2.0.0.beta.22/lib/rspec/core/backward_compatibility.rb:20:in `const_missing'
/home/matchu/.rvm/gems/[email protected]/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/[email protected]/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 был в бета-версии. Как я могу отладить эту проблему? Спасибо!
Ответы
Ответ 1
В отличие от запуска вашего приложения на производстве, задача Rake не загружает всю вашу базу кода. Вы можете увидеть его в источнике:
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
устанавливается в true
в задаче :environment
Rake.
Самый простой способ - просто require
модель, которая вам нужна. Однако, если вам действительно нужно, чтобы все приложение загружалось в задачу Rake, его довольно просто загрузить:
Rails.application.eager_load!
Причина всей этой работы в разработке заключается в том, что Rails автоматически загружает ваши модели в режиме разработки. Это также работает из задачи Rake.
Ответ 2
В вашей среде /production.rb вы должны добавить следующее:
config.dependency_loading = true if $rails_rake_task
Он решил проблему для меня.
(Примечание: это должно быть добавлено ПОСЛЕ вызова config.threadsafe!)
Ответ 3
Просто нашел еще один: я разрабатывал на windows, развертывая на Heroku. Веб-приложение и консоль rails работали нормально, но не могли загрузить модель rake-задач и даже прямых запросов. Оказалось, что я рассеянно создал файл модели как Model.rb
вместо model.rb
- системно-зависимая чувствительность к регистру.