Understanding Rails Engines
The Problem: Modularizing and Reusing Code
In large Ruby on Rails applications, keeping the codebase modular and manageable is a challenge. Often, multiple applications share functionality like authentication, admin dashboards, or payment systems. Copy-pasting code between apps leads to maintenance headaches and inconsistency.
Rails Engines solve this by providing a way to encapsulate features or functionality into reusable, self-contained modules.
What is a Rails Engine?
A Rails Engine is a mini Rails application that can be mounted inside another application. It has its own models, views, controllers, and even routes. Engines are ideal for creating reusable components shared across multiple applications.
When to Use Rails Engines
- Shared Functionality: When multiple applications need the same features, such as authentication or reporting.
- Modularity: To separate large parts of an application into smaller, independent modules.
- Reusable Gems: When building functionality to distribute as a Ruby gem.
Setting Up a Simple Rails Engine
Step 1: Create a New Engine
Run the following command to generate a Rails Engine:
rails plugin new my_engine --mountable
The --mountable
option creates a fully isolated engine with its own namespace.
Step 2: Directory Structure
The engine’s structure is similar to a Rails application but scoped to the engine:
my_engine/
├── app/
│ ├── controllers/
│ ├── models/
│ ├── views/
├── config/
│ ├── routes.rb
├── lib/
│ ├── my_engine/
│ │ ├── engine.rb
│ ├── my_engine.rb
Step 3: Configure the Engine
Edit lib/my_engine/engine.rb
to define your engine:
module MyEngine
class Engine < ::Rails::Engine
isolate_namespace MyEngine
end
end
The isolate_namespace
ensures that all models, controllers, and routes are scoped under the MyEngine
namespace.
Step 4: Add Routes
Define routes in config/routes.rb
:
MyEngine::Engine.routes.draw do
resources :posts
end
Step 5: Mount the Engine
In the host application’s config/routes.rb
, mount the engine:
Rails.application.routes.draw do
mount MyEngine::Engine => "/my_engine"
end
Step 6: Create a Controller
Add a controller in app/controllers/my_engine/posts_controller.rb
:
module MyEngine
class PostsController < ApplicationController
def index
render plain: "Welcome to MyEngine!"
end
end
end
Step 7: Use the Engine
Start the Rails server and navigate to /my_engine/posts
in the browser.