Class
Rails::Engine
<
Railtie

Rails::Engine allows you to wrap a specific Rails application
or subset of functionality and share it with other applications or within a
larger packaged application. Every Rails::Application is just
an engine, which allows for simple feature and application sharing.

Any Rails::Engine is also a Rails::Railtie, so
the same methods (like rake_tasks and generators)
and configuration options that are available in railties can also be used
in engines.

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/*, and 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.

The 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. If you have an
app/services folder for example, it will be added by default.

Endpoint

An engine can also be a Rack application. It can be
useful if you have a Rack application that you
would like to wrap with Engine and provide with some of the
Engine's features.

MyEngine is mounted at /blog, and
/blog/omg points to application's controller. In such a
situation, requests to /blog/omg will go through
MyEngine, and if there is no such route in
Engine's routes, it will be dispatched to
main#omg. It's much better to swap that:

Normally when you create controllers, helpers and models inside an engine,
they are treated as if they were created inside the application itself.
This means that all helpers and named routes from the application will be
available to your engine's controllers as well.

However, sometimes you want to isolate your engine from the application,
especially if your engine has its own router. To do that, you simply need
to call isolate_namespace. This method requires you to pass a
module where all your controllers, helpers and models should be nested to:

With such an engine, everything that is inside the MyEngine
module will be isolated from the application.

Consider this controller:

module MyEngine
class FooController < ActionController::Base
end
end

If the MyEngine engine is marked as isolated,
FooController only has access to helpers from
MyEngine, and url_helpers from
MyEngine::Engine.routes.

The next thing that changes in isolated engines is the behavior of routes.
Normally, when you namespace your controllers, you also need to namespace
the related routes. With an isolated engine, the engine's namespace is
automatically applied, so you don't need to specify it explicitly in
your routes:

MyEngine::Engine.routes.draw do
resources :articles
end

If MyEngine is isolated, The routes above will point to
MyEngine::ArticlesController. You also don't need to use
longer url helpers like my_engine_articles_path. Instead, you
should simply use articles_path, like you would do with your
main application.

To make this behavior consistent with other parts of the framework,
isolated engines also have an effect on ActiveModel::Naming.
In a normal Rails app, when you use a namespaced model such as
Namespace::Article, ActiveModel::Naming will
generate names with the prefix “namespace”. In an isolated engine, the
prefix will be omitted in url helpers and form fields, for convenience.

Additionally, an isolated engine will set its own name according to its
namespace, so MyEngine::Engine.engine_name will return
“my_engine”. It will also set MyEngine.table_name_prefix to
“my_engine_”, meaning for example that MyEngine::Article will
use the my_engine_articles database table by default.

Since you can now mount an engine inside application's routes, you do
not have direct access to Engine's
url_helpers inside Application. When you mount an
engine in an application's routes, a special helper is created to allow
you to do that. Consider such a scenario:

Note that the :as option given to mount takes the
engine_name as default, so most of the time you can simply
omit it.

Finally, if you want to generate a url to an engine's route using
polymorphic_url, you also need to pass the engine helper.
Let's say that you want to create a form pointing to one of the
engine's routes. All you need to do is pass the helper as the first
element in array with attributes for url:

form_for([my_engine, @user])

This code will use my_engine.user_path(@user) to generate the
proper route.

Isolated engine's helpers

Sometimes you may want to isolate engine, but use helpers that are defined
for it. If you want to share just a few specific helpers you can add them
to application's helpers in ApplicationController:

It will include all of the helpers from engine's directory. Take into
account that this does not include helpers defined in controllers with
helper_method or other similar solutions, only helpers defined in the
helpers directory will be included.

Migrations & seed data

Engines can have their own migrations. The default path for migrations is
exactly the same as in application: db/migrate

To use engine's migrations in application you can use the rake task
below, which copies them to application's dir:

rake ENGINE_NAME:install:migrations

Note that some of the migrations may be skipped if a migration with the
same name already exists in application. In such a situation you must
decide whether to leave that migration or rename the migration in the
application and rerun copying migrations.

If your engine has migrations, you may also want to prepare data for the
database in the db/seeds.rb file. You can load that data using
the load_seed method, e.g.

MyEngine::Engine.load_seed

Loading priority

In order to change engine's priority you can use
config.railties_order in the main application. It will affect
the priority of loading views, helpers, assets, and all the other files
related to engine or application.