Rails Engines

Why?

Engines can be considered miniature applications that provide functionality to their host applications.

A Rails application is actually just a "supercharged" engine, with the Rails::Application class inheriting a lot of its behavior from Rails::Engine.

So, lets create engine

prooof.png

$ bin/rails plugin new dummy_e --mountable

Confusing documentation

engine_g_without_full_opt.png

With –full flag it works

engine_g_with_full_opt.png

Isolate namespace

purpose_of_isolate_workspace.png

Expectations

isolate_namespace.png

Reality

isolate_namespace_reality.png

Add article resource

generated_resource_article.png

Look at the routes

rake_routes_after_genertion.png

Sh*t

routes_fail.png

Fix

change_routes_to_work.png

Look again

routes_normal.png

Add comments

generate_resource.png

Try to run app

load_error.png

Quick fix

quick_fix.png

Run again

error_again.png

Run engines migrations

No rake, only rails

rake_issue_v2.png

Copy migrations

copy_migrations.png

Done

done.png

Overriding Models and Controllers

There is ability to override engine class from main app.

  • Documentation says that it could be done whith Class#eval
  • Or with ActiveSupport::Concern

Prepare to overriding with eval

# engine/lib/dummy_e/engine.rb
module DummyE
  class Engine < ::Rails::Engine
    isolate_namespace DummyE

    config.to_prepare do
      Dir.glob(Rails.root + 'app/decorators/**/*_decorator*.rb').each do |c|
	require_dependency(c)
      end
    end
  end
end

In the engine

# engine/app/models/article.rb
module DummyE
  class Article < ApplicationRecord
    has_many :comments

    def summary
      "#{title}"
    end
  end
end

In the main app

# main_app/app/decorators/models/dummy_e/article_decorator.rb
DummyE::Article.class_eval do
  def summary
    "#{title} - #{text.squeeze}"
  end
end

Result

override_result.png

P.S

  • Write documentation.
  • Documentation with wrong examples is the worst thing. Do not write this kind of docs.

Thanks

Code: