How to prevent class unloading in Ruby on Rails
Let’s assume you have a class that holds a connection to an external system, and you don’t want Rails auto(un)loading to mess with that. The advice the rails documentation gives you in this case is simple and correct: Just don’t let rails autoload your class, instead, require it yourself.
require 'my_persistent_class'
There is one gotcha to this, and a gotcha that conflicts with the natural ordering tendency that every programmer should have. Let’s say you’re extending a rails model with FeatureX. It will come natural to you to name that module RailsModel::FeatureX. This has consequences.
There is no real way to ‘load’ that RailsModel by using a require – when would you do it? During initialization process, this fails because rails obviously isn’t in place yet. And later on – rails will be in place and the RailsModel class will already be in the fangs of autoloading.
And the next time rails autounloads/ autoloads classes, RailsModel – and with it FeatureX – will be reloaded as well. Darn. The solution to this is really simple, but it took me a while to figure this out: Just don’t include the FeatureX class in the namespace of RailsModel. Then doing this in your environment.rb will ensure that your FeatureX isn’t unloaded:
config.after_initialize do
require 'feature_x'
FeatureX.set_some_persistent_attribute :foo => :bar
end
Btw: Global variables are really evil.