Rails Engine Intro

You probably already used a lot of gems that are actually a rails engine, e.g. ActiveAdmin, Devise, Forem, Spree, ...

I needed to create an independent part on my previous project, and it should not share the resources with the rest of the project. Initially, I thoght to create just a namespace, put controllers, views inside and use it like that. But then, I noticed that I should separate my assets, so this subproject do not load unnecessary javascript/css files.

Then I remembered, Rails engine will do the trick. It works as a gem, that you can use inside your app, by requiring it in Gemfile.

$ cd myapp
$ rails plugin new admin --mountable

This will generate a admin/ directory inside your myapp directory. It will contain app, bin, config, lib, test folders and Gemfile, Rakefile and admin.gemspec.

Edit your gemspec file. Initially, you will have "TODO" texts. In order to run bundle install you must remove "TODO" or "FIXME" form gemspec file.

Next, open your Gemfile and add:

gem 'admin', path: 'admin'

This will load your plugin as a gem. Now, we need to tell the router which url to point to our plugin. Run bundle install.

mount Admin::Engine, at: "/admin/"

Lets create welcome_controller.rb inside the myapp/admin/app/controllers/admin/welcome_controller.rb.

class Admin::WelcomeController < Admin::ApplicationController

    def index
    end
end

and appropriate view located at myapp/admin/app/views/admin/welcome/index.html.erb.

<h1>Hello World!</h1>

Open myapp/admin/config/routes.rb and set root:

Admin::Engine.routes.draw do
  root 'welcome#index'
end

Start the server with rails s inside myapp directory, and open http://localhost:3000/admin/. If everything went ok, you should see "Hello World!" message.

You can define models for a engine itself, or you can access the ones from the hosting app.

If you want to use some external gems, you should add a dependency in myapp/admin/admin.gemspec.

s.add_dependency 'gem_you_want_to_include'

And then, you need to require it in myapp/admin/lib/admin/engine.rb

require 'gem_you_want_to_include'

Do not forget to run bundle install after these changes.

For further reading, please read Getting Started with Engines.