This project is archived and is in readonly mode.
Gem tasks fail when cache_classes=true
Reported by Richie Vos | December 10th, 2008 @ 06:31 PM | in 2.x
If I have a model like:
# MyModel.rb
require 'fastercsv'
class MyModel < ActiveRecord::Base; end
and in my config file I have
# ....
config.cache_classes = true
config.gem 'fastercsv'
and I don't have the fastercsv gem installed, the rake gems tasks cannot run.
In initializer.rb, cache_classes=true ends up kicking off the class preloading, which then ends up trying to require a gem that's not yet been installed, ... (another gems:install catch-22).
The easy fix is fairly straightforward (will provide a patch & tests), but load_application_classes needs to just check for $rails_gem_installer to be set, and if so don't try and do the preloading.
It kind of seems like the $rails_gem_installer flag is a bit of a hack, and that really rake gems:install should be setting what initializer steps get ran (seems like very few of them), but that's a bigger fix.
Here's a workaround you can drop into environment.rb in the mean-time
# this is a workaround for a Rails issue where cache_classing can lead to not yet installed
# gems to cause the gem:install to fail
module Rails
class Initializer
def load_application_classes_with_check_for_gem_loading
load_application_classes_without_check_for_gem_loading unless $rails_gem_installer
end
alias_method :load_application_classes_without_check_for_gem_loading, :load_application_classes
alias_method :load_application_classes, :load_application_classes_with_check_for_gem_loading
end
end
Comments and changes to this ticket
-
Matt Jones December 20th, 2008 @ 09:16 PM
Don't use "require 'fastercsv'" in your model - config.gem will do it for you if the gem is available.
-
dstrelau January 7th, 2009 @ 05:50 PM
- Tag changed from 2.2.2, bug, cache_classes, initializer, load_application_classes, railties to bug, cache_classes, edge, gems, initializer, load_application_classes, patch, railties, rake
Actually, this is still a problem, even when not using require in the model. Initializer#load_application_classes runs, even when executing a gems task, which means that if the gem isn't installed, you end up with errors. Note this only happens in production or when
config.cache_classes = true
.Here is how you can replicate: 1) Uninstall 'thoughtbot-paperclip' if you have it installed 2) New rails project, with vendored rails 3)
config.gem 'thoughtbot-paperclip', :lib => 'paperclip', :source => 'http://gems.github.com'
4)script/generate model foo
5)class Foo < AR; has_attached_file :image; end
6) RAILS_ENV=production rake gemsPatch against master attached, which just doesn't loaded classes if $rails_gem_installer is set:
def load_application_classes if configuration.cache_classes && !$rails_gem_installer
PS: I'd love to see this backported into 2.2 as well. :)
-
dstrelau January 29th, 2009 @ 04:22 PM
- Tag changed from bug, cache_classes, edge, gems, initializer, load_application_classes, patch, railties, rake to bug, gems, initializer, patch, railties, rake, tiny
I'm going to bump this, in the hopes that someone might take a look and care, seeing as this bug essentially makes rake gems:install useless for satisfying gem dependencies on a production server.
-
Matt Jones February 18th, 2009 @ 01:15 AM
Take a look at #1750 - I've attached a patch that basically bails out of the initializer if rake gems tasks are being run and gems are missing. This should stop anything like this from happening.
Also see #802, which has probably handled this case already by turning off eager loading in all rake tasks.
-
Pratik August 8th, 2009 @ 08:54 PM
- State changed from new to stale
Please reopen if this is still an issue.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>