Search

Intro to Rails Engines

Brian Gardner

4 min read

Dec 19, 2012

Intro to Rails Engines

I have recently been hearing quite a bit about people using Rails engines. I was intrigued about how they are used and how they integrate into a Rails application, and I soon got a chance to satisfy my curiosity by working on a couple projects that used these engines. Here I will talk a little about what Rails engines are used for and how they are integrated into a Rails application.

What’s a Rails Engine?

So the first question you may be asking is, what the heck is a Rails engine, anyway? In short, it allows you to wrap up a Rails application or a subset of its functionality in a way that makes it easy to share it with other applications. This plug-and-play sort of functionality is quite similar to how Ruby gems work. In fact, prior to Rails 3.0, all Ruby gems automatically behaved as engines, and since Rails 3.0 all Rails applications are just engines. And just like a Rails application, a Rails engine is also a Railtie, so it has access to rake tasks and generators that can be used in the engine. Since Rails 3.0 has come out, if you want a gem to automatically behave as a Rails engine, you have to define an engine somewhere inside of the gem’s lib folder.

module MyEngine
     class Engine < Rails::Engine
     end
end

Types of Engines

When creating a Rails engine, there is one special thing to take note of, and this is the difference between a full engine and a mountable one. In a full engine, the parent application inherits all of the routes defined in the engine, so it is not necessary to define anything in parent/config/routes.rb. Simply specifying the Engine in the gem file of the parent application is enough for it to have access to all of the engines models, controllers, routes, etc. For a mountable engine, its namespace is isolated by default:

module MyEngine
     class Engine < Rails::Engine
          isolate_namespace MyEngine
     end
end

The routes of the engines are namespaces and it needs to be mounted in the parent app’s routes file to be used.

Parent::Application.routes.draw do
     mount MyEngine::Engine => '/engine', as: 'my_engine'
end

Helpers

Once you have your engine mounted inside of the parent application, some helpers are defined to help specify the routes. Inside of the parent app above there would he a helper named ‘my_engine’ that would allow you to access its routes like:

my_engine.root_url

From the engine, there is also a helper named ‘main_app’ that is defined that allows the engine to access the parent app’s routes.

MIGRATIONS AND SEEDING DATA

The parent application also needs to be able to install the migrations from the Rails engine. In order to copy over the migration files from the engine to the parent app you can run:

rake MyEngine:install:migrations

A migration would be skipped if one with the same name already exists within the application. Once the migrations have been copied over they can be loaded by running

rake db:migrate

If the engine has any seed data in the db/seeds.rb file it can be loaded by running

MyEngine::Engine.load_seed

tests

Finally, testing a Rails engine is a little different than just testing a Rails application. Inside of your test directory there is a dummy app, which is a Rails application that is used during testing. Your engine is automatically loaded into the dummy app and all of your tests are run from the dummy app’s environment. If you find it necessary, you can generate controllers, models or views in the dummy app to use while testing your engine. Special consideration must be taken when writing controller tests. Since the requests are going through the dummy application you need to be more specific when using the get, post, etc. methods. This is where the :use_route option comes in for in these methods.

get :index, use_route: :my_engine

This will perform a get request to the index action of the controller, but it specifies that you want to use the routes from my_engine to get there rather than those in the dummy application.

summary

Working with Rails engines has been an insightful experience and I have learned quite a bit about how they work. It is always fun to find out about new technologies to use, and I’m looking forward to continuing my exploration of Rails Engines and finding uses for them in my future projects.

Resources:
Rails Api
Railscast

Josh Justice

Reviewer Big Nerd Ranch

Josh Justice has worked as a developer since 2004 across backend, frontend, and native mobile platforms. Josh values creating maintainable systems via testing, refactoring, and evolutionary design, and mentoring others to do the same. He currently serves as the Web Platform Lead at Big Nerd Ranch.

Speak with a Nerd

Schedule a call today! Our team of Nerds are ready to help

Let's Talk

Related Posts

We are ready to discuss your needs.

Not applicable? Click here to schedule a call.

Stay in Touch WITH Big Nerd Ranch News