Skip to content

Commit

Permalink
Add docs for Railtie, Engine, Plugin and Application.
Browse files Browse the repository at this point in the history
  • Loading branch information
josevalim committed Feb 2, 2010
1 parent 12f595b commit 781d0a9
Show file tree
Hide file tree
Showing 6 changed files with 265 additions and 62 deletions.
37 changes: 37 additions & 0 deletions railties/lib/rails/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,43 @@
require 'rails/engine'

module Rails
# In Rails 3.0, a Rails::Application object was introduced which is nothing more than
# an Engine but with the responsibility of coordinating the whole boot process.
#
# Opposite to Rails::Engine, you can only have one Rails::Application instance
# in your process and both Rails::Application and YourApplication::Application
# points to it.
#
# In other words, Rails::Application is Singleton and whenever you are accessing
# Rails::Application.config or YourApplication::Application.config, you are actually
# accessing YourApplication::Application.instance.config.
#
# == Initialization
#
# Rails::Application is responsible for executing all railties, engines and plugin
# initializers. Besides, it also executed some bootstrap initializers (check
# Rails::Application::Bootstrap) and finishing initializers, after all the others
# are executed (check Rails::Application::Finisher).
#
# == Configuration
#
# Besides providing the same configuration as Rails::Engine and Rails::Railtie,
# the application object has several specific configurations, for example
# "allow_concurrency", "cache_classes", "consider_all_requests_local", "filter_parameters",
# "logger", "metals", "reload_engines", "reload_plugins" and so forth.
#
# Check Rails::Application::Configuration to see them all.
#
# == Routes
#
# The application object is also responsible for holding the routes and reloading routes
# whenever the files change in development.
#
# == Middlewares and metals
#
# The Application is also responsible for building the middleware stack and setting up
# both application and engines metals.
#
class Application < Engine
autoload :Bootstrap, 'rails/application/bootstrap'
autoload :Configurable, 'rails/application/configurable'
Expand Down
4 changes: 4 additions & 0 deletions railties/lib/rails/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

module Rails
module Configuration
# Holds coonfiguration shared between Railtie, Engine and Application.
module Shared
def middleware
@@default_middleware_stack ||= ActionDispatch::MiddlewareStack.new.tap do |middleware|
Expand Down Expand Up @@ -87,6 +88,8 @@ def options
end
end

# Generators configuration which uses method missing to wrap it in a nifty DSL.
# It also allows you to set generators fallbacks and aliases.
class Generators #:nodoc:
attr_accessor :aliases, :options, :fallbacks, :colorize_logging

Expand Down Expand Up @@ -119,6 +122,7 @@ def method_missing(method, *args)
end
end

# Holds configs deprecated in 3.0. Will be removed on 3.1.
module Deprecated
def frameworks(*args)
raise "config.frameworks in no longer supported. See the generated " \
Expand Down
84 changes: 84 additions & 0 deletions railties/lib/rails/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,90 @@
require 'rails/railtie'

module Rails
# Rails::Engine allows you to wrap a specific Rails application and share it accross
# different applications. Since Rails 3.0, your Rails::Application is nothing
# more than an Engine, thus your engines will behave much more closer to an application
# since then.
#
# Any Rails::Engine is also a Rails::Railtie, so the same methods (like rake_tasks and
# generators) and configuration available in the latter can also be used in the former.
#
# == Creating an Engine
#
# In Rails versions before to 3.0, your gems automatically behaved as Engine, however
# this coupled Rails to Rubygems. Since Rails 3.0, if you want a gem to automatically
# behave as Engine, you have to specify an Engine for it somewhere inside your plugin
# lib folder (similar with how we spceify a Railtie):
#
# # lib/my_engine.rb
# module MyEngine
# class Engine < Rails::Engine
# engine_name :my_engine
# end
# end
#
# Then ensure that this file is loaded at the top of your config/application.rb (or in
# your Gemfile) and it will automatically load models, controllers, helpers and metals
# inside app, load routes at "config/routes.rb", load locales at "config/locales/*",
# load tasks at "lib/tasks/*".
#
# == Configuration
#
# Besides the Railtie configuration which is shared across the application, in a
# Rails::Engine you can access load_paths, eager_load_paths and load_once_paths,
# which differently from a Railtie, are scoped to the current Engine.
#
# Example:
#
# class MyEngine < Rails::Engine
# # config.middleware is shared configururation
# config.middleware.use MyEngine::Middleware
#
# # Add a load path for this specific Engine
# config.load_paths << File.expand_path("../lib/some/path", __FILE__)
# end
#
# == Paths
#
# Since Rails 3.0, both your Application and Engines does not have hardcoded paths.
# This means that you are not required to place your controllers at "app/controllers",
# but in any place which you find convenient.
#
# For example, let's suppose you want to lay your controllers at lib/controllers, all
# you need to do is:
#
# class MyEngine < Rails::Engine
# paths.app.controllers = "lib/controllers"
# end
#
# You can also have your controllers being loaded from both "app/controllers" and
# "lib/controllers":
#
# class MyEngine < Rails::Engine
# paths.app.controllers << "lib/controllers"
# end
#
# The available paths in an Engine are:
#
# class MyEngine < Rails::Engine
# paths.app = "app"
# paths.app.controllers = "app/controllers"
# paths.app.helpers = "app/helpers"
# paths.app.models = "app/models"
# paths.app.metals = "app/metal"
# paths.app.views = "app/views"
# paths.lib = "lib"
# paths.lib.tasks = "lib/tasks"
# paths.config = "config"
# paths.config.initializers = "config/initializers"
# paths.config.locales = "config/locales"
# paths.config.routes = "config/routes.rb"
# end
#
# Your Application class adds a couple more paths to this set. And as in your Application,
# all folders under "app" are automatically added to the load path. So if you have
# "app/observers", it's added by default.
#
class Engine < Railtie
autoload :Configurable, "rails/engine/configurable"
autoload :Configuration, "rails/engine/configuration"
Expand Down
15 changes: 15 additions & 0 deletions railties/lib/rails/plugin.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
require 'rails/engine'

module Rails
# Rails::Plugin is nothing more than a Rails::Engine, but since it's loaded too late
# in the boot process, it does not have the same configuration powers as a bare
# Rails::Engine.
#
# Opposite to Rails::Railtie and Rails::Engine, you are not supposed to inherit from
# Rails::Plugin. Rails::Plugin is automatically configured to be an engine by simply
# placing inside vendor/plugins. Since this is done automatically, you actually cannot
# declare a Rails::Engine inside your Plugin, otherwise it would cause the same files
# to be loaded twice. This means that if you want to ship an Engine as gem it cannot
# be used as plugin and vice-versa.
#
# Besides this conceptual difference, the only difference between Rails::Engine and
# Rails::Plugin is that plugins automatically load the file "init.rb" at the plugin
# root during the boot process.
#
class Plugin < Engine
def self.inherited(base)
raise "You cannot inherit from Rails::Plugin"
Expand Down
Loading

0 comments on commit 781d0a9

Please sign in to comment.