From 2a833d7bd8c7d76d833fc248a113fb2f1cfe6d2b Mon Sep 17 00:00:00 2001 From: Ryan Bigg Date: Thu, 15 Apr 2010 08:10:28 +1000 Subject: [PATCH] Cover more of the Rails initialization process, regarding the internals of YourApp::Application inheritance from Rails::Application and more. --- railties/guides/source/initialization.textile | 66 ++++++++++++++++++- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/railties/guides/source/initialization.textile b/railties/guides/source/initialization.textile index 96d6998e1c..cccbb9df06 100644 --- a/railties/guides/source/initialization.textile +++ b/railties/guides/source/initialization.textile @@ -1819,7 +1819,7 @@ On the surface, this looks like a simple class inheritance. There's more underne end -We do not already have a +Rails.application+, so instead this resorts to calling +super+. +Rails::Application+ descends from +Rails::Engine+ and so will call the +inherited+ method in +Rails::Engine+, but before that it's important to note that +called_from+ is defined an +attr_accessor+ on +Rails::Engine+: +We do not already have a +Rails.application+, so instead this resorts to calling +super+. +Rails::Application+ descends from +Rails::Engine+ and so will call the +inherited+ method in +Rails::Engine+ (in _railties/lib/rails/engine.rb_), but before that it's important to note that +called_from+ is defined an +attr_accessor+ on +Rails::Engine+ and that +YourApp::Application+ is not an +abstract_railtie+: def inherited(base) @@ -1835,8 +1835,68 @@ We do not already have a +Rails.application+, so instead this resorts to calling end -This +called_from+ setting looks a little overwhelming to begin with, but the short end of it is that it returns the route to your application's config directory, something like: _/home/you/yourapp/config_. After +called_from+ has been set, +super+ is again called and this means the +Rails::Railtie#inherited+ method. - +This +called_from+ setting looks a little overwhelming to begin with, but the short end of it is that it returns the route to your application's config directory, something like: _/home/you/yourapp/config_. After +called_from+ has been set, +super+ is again called and this means the +Rails::Railtie#inherited+ method (in _railties/lib/rails/railtie.rb_): + + + def inherited(base) + unless base.abstract_railtie? + base.send(:include, self::Configurable) + subclasses << base + end + end + + +Again, +YourApp::Application+ will return false for +abstract_railtie+ and so the code inside the +unless+ will be ran. The first line: + + + base.send(:include, self::Configurable) + + +includes the +self::Configurable+ module, with self being +Rails::Application+ in this context: + + + module Rails + class Application + module Configurable + def self.included(base) + base.extend ClassMethods + end + + module ClassMethods + def inherited(base) + raise "You cannot inherit from a Rails::Application child" + end + end + + def config + @config ||= Application::Configuration.new(self.class.find_root_with_flag("config.ru", Dir.pwd)) + end + end + end + end + + +The inclusion of the +Rails::Application::Configurable+ module triggers the +included+ method in here which extends +YourApp::Application+ with the +Rails::Application::Configurable::ClassMethods+. + +Now that the chain of +super+ calls is done, we'll go back to the original +inherited+ method in +Rails::Application+ and the final line in this method: + + + Rails.application = base.instance + + ++base+ in this case is +YourApp::Application+ and calling +instance+ on this will return an instance of +YourApp::Application+ through the +instance+ method defined here: + + + def instance + if self == Rails::Application + Rails.application + else + @@instance ||= new + end + end + + ++self+ in this case is +YourApp::Application+, so it won't match to +Rails::Application+ so instead the +new+ method is called which calls the +initialize+ method.