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.

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
    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 and helpers 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 autoload_paths, eager_load_paths and autoload_once_paths, which differently from a Railtie, are scoped to the current Engine.

Example:

  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

Paths

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:

  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.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.

Aliases

  • railtie_name
Show files where this class is defined (3 files)
Register or log in to add new notes.