Post

Engine on Rails

Engines are small applications which provides functionality to their host applications. A Rails application is a engine with Rails::Application class inheriting a lot of behaviour from Rails::Engine. So Rails application and engine are alomost same thing and share common structure with slight differences.

Engines also related with plugins, both shares lib/ directory structure, and both generated using rails plugin new generator. Engine is considered as full plugin using --full in generator while --mountable option includes features of full and some others. An engine can be a plugin and plugin can be an engine.

Some example of engines are: Devise for authenticating parent application, Thredded for forum functionlity, Spree for ecommerce, Refinery CMS for CMS application.

Create a Base application (e.g: base_app)

Create engine e.g: engine_app with following command:

  rails new plugin engine_app --mountable

Customize engine_app.gemspec file and edit, homepage, summary, description, etc as per your requirements.

Go to base_app - Gemfile

  gem 'engine_app', path: 'lib/engine_app'
  bundle install

When everything is Ok, we will get some message like: Using engine_app 0.0.1 from source at lib/engine_app

How to make plugins - routes easy?

Go to routes.rb file of base app and paste the code:

mount EngineApp::Engine, at: '/engine_app'

or

Go to plugins app/lib/engine_app/engine.rb

isolate_namespace EngineApp

initializer "engine_app", before: :load_config_initializers do |app|
      Rails.application.routes.append do
          mount EngineApp::Engine, at: '/engine_app'
      end
end

Now it is possible to run rake routes and we can see all engines routes

e.g: engine_app /engine_app EngineApp::Engine

How to check Plugins Rails Console?

Go to main app
> rails console
> EngineApp::Article.new

How to make MVC in base and inside engines?

To make model controller inside base go to base dir or else go to engine dir

Rails Engine Migrations

Base app has no knowledge of Engine migrations, we need to customize it or manually we need to run command:

i) Manually we can run following command:

rake engine_app:install:migrations

ii) go to lib/engine.rb file and paste the following code

 initializer "engine_app", before: :load_config_initializers do |app|
     config.paths["db/migrate"].expanded.each do |expanded_path|
         Rails.application.config.paths["db/migrate"] << expanded_path
     end
 end

Now rake db:migrate will work from base application

How to access plugins and base app’s controller action?

For e.g: link_to 'Home', root_path, will not work if we want to access engines resources because engine won’t able to understand root_path for it. So we need following codes:

link_to 'Home', main_app.root_path
link_to 'Plugin Home', engine_app.articles_path

How to layout in base and engines?

We have to call layouts inside application controller or wherever required and it can be accessed by:

layouts 'application' # will call base layouts
layouts 'engine_app/application' # will call plugin layouts

How to include gems inside engines?

Go to .gemspec file e.g: engine_app.gemspec

Gem::Specification.new do |s|
  s.add_dependency "devise"
  s.add_dependency 'authority', '~> 3.1'
end

This post is licensed under CC BY 4.0 by the author.