278 | Chapter 9: Incorporating and Extending Rails
Og::Mixin.autoload :Orderable, 'og/model/orderable'
# 4. Models must be loaded before Og starts
Dir[File.join(RAILS_ROOT, 'app', 'models', '*.rb')].each(&method(:load))
# 5. Read in database.yml and start Og
config = YAML.load_file(File.join(RAILS_ROOT, 'config', 'database.yml'))
$og = Og.start(config[RAILS_ENV].symbolize_keys)
This does several things to initialize Og:
- First, as a sanity check, we use thegemmethod to specify the exact gem version
we installed. As long as the gem specification (og.gemspec) specifies a version of
0.50.0, that is the version that RubyGems will recognize. Therefore, we can
refresh the Og gem from edge for minor changes without updating this line. - Theclass Objectblock is in place to work around an incompatibility between
Ruby Facets and RailsDependencies. Og’s initialization methods load methods in
Facets using therequiremethod. However,Dependenciesoverrides therequire
method to keep track of the modules and classes being defined by files as they
are required. The new version ofrequirecauses problems and prevents Og’s
dependencies from being loaded properly.
To resolve this, we temporarily disable all specialrequirefunctionality while
loading Og. First, we store away a copy of the fully functionalrequire, with
RubyGems andDependencies,asrequire_withrubygems. Then we aliasgem
original_require(the no-frills standard Rubyrequire, which RubyGems help-
fully aliases) asrequire, so that Og doesn’t notice any of the sneaky things we
are doing. When Og is loaded, we can put the full-featuredrequirewith
rubygems back into place.
Notice that the actual call requiring Og needs to userequire_with_rubygemsso
that it will find the gem. We do all of this manipulation so that Og’s nested calls
torequire will use the Ruby version, not the RubyGems/Rails version. - In this example, we are mixing theOrderablemodule into our class; Og uses
mixins to add behavior to model classes, where ActiveRecord would convention-
ally use class methods (in this example,acts_as_list). UsingModule#autoload,
we designate thatOg::Mixin::Orderablecan be found under Og’s source tree at
og/model/orderable.rb. - As mentioned before, Og needs to see all of the models when it starts, so that it
can inject them with Og model methods. (This is in contrast to the
ActiveRecord and DataMapper method of requiring all models to inherit from a
common base class.) But Rails usesDependenciesto lazy-load models; if we do
not explicitly load them here, they will not exist until their name is referenced.