Skip to content

Instantly share code, notes, and snippets.

@miguelac
Forked from maxivak/readme.md
Created July 27, 2019 08:15
Show Gist options
  • Select an option

  • Save miguelac/51063c43e0a977d35b4781bb3d5bdde7 to your computer and use it in GitHub Desktop.

Select an option

Save miguelac/51063c43e0a977d35b4781bb3d5bdde7 to your computer and use it in GitHub Desktop.
Integrating Gem/Engine and Main Rails App

Integrate Gem/Engine and main Rails app

Overview

(#extend-engine-class)

Improving (Extending or overriding) Engine functionality

A common task after including Engine in your Rails app is extending some classes (models, controllers, other classes) defined in the Engine.

It can be done using Decorator pattern.

There are two options of extending a class defined in Engine:

  • use Class@class_eval
  • use ActiveSupport::Concern

For simple class modifications, use Class#class_eval.

For complex class modifications, consider using ActiveSupport::Concern.

Read more in Rails guides.

use Class#class_eval to override class defined in Gem/Engine

# lib/myengine/engine.rb
module Myengine
  class Engine < ::Rails::Engine
    isolate_namespace Myengine
 
    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:

# Blorgh/app/models/article.rb
 
class Article < ActiveRecord::Base
  has_many :comments
  
  def summary
    "#{title}"
  end
end

in the main app:

# MyApp/app/decorators/models/blorgh/article_decorator.rb
 
Myengine::Article.class_eval do
  # add new method
  def time_since_created
    Time.current - created_at
  end
  
  # override the method
  def summary
    "#{title} - #{truncate(text)}"
  end
  
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment