Rails::Engine allows you to wrap a specific Rails application and share it accross different applications. Since Rails 3.0, every Rails::Application is nothing more than an Engine, allowing you to share it very easily.
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):
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 and helpers inside app, load routes at “config/routes.rb”, load locales at “config/locales/*”, load tasks at “lib/tasks/*”.
Besides the Railtie configuration which is shared across the application, in a Rails::Engine you can access autoload_paths, eager_load_paths and autoload_once_paths, which differently from a Railtie, are scoped to the current Engine.
class MyEngine < Rails::Engine # Add a load path for this specific Engine config.autoload_paths << File.expand_path("../lib/some/path", __FILE__) initializer "my_engine.add_middleware" do |app| app.middleware.use MyEngine::Middleware end end
Since Rails 3.0, both your Application and Engines do 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:
You can also have your controllers being loaded from both “app/controllers” and “lib/controllers”:
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.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.
railties/lib/rails/engine.rb railties/lib/rails/engine/configuration.rb railties/lib/rails/engine/configurable.rb