# This simple solution open-classes the controller/model in the main app
# to add or overwrite methods.
# A drawback of this solution is that you won't be able to access the original
# method by using +super+.
# engine: app/controllers/myengine/my_controller.rb
# This is the controller in our engine with a index method defined.
module MyEngine
class MyController < ApplicationController
def index
end
end
end
# app: app/controllers/myengine/my_controller.rb
# Now we open-class the engines controller in our app that uses the engine
# and overwrite the +index+ method.
# We need to require the engines controller first because Rails would only load
# the first controller it finds and that is our overwritten controller here.
require_dependency MyEngine::Engine.config.root.join('app', 'controllers', 'myengine', 'my_controller.rb').to_s
class MyEngine::MyController
def index
end
end
# Source
# http://stackoverflow.com/questions/7719633/how-to-extend-rails-engines-controllers-properly
# http://edgeguides.rubyonrails.org/engines.html#overriding-models-and-controllers
# A modification of this solution is using the decorator pattern. It also modifies
# the engine controller/model by open-classing but the extensions/overwrites
# are defined in another directory for example the lib directory.
# I don't like that pattern because I think it hides to modifications too much.
# Also the solution on edgeguides loads the decorators in the main app
# via initializer code in the engine. That feels weired for example
# ActiveAdmin places code in +app/decorators+ so now we would load that code
# twice...
# This solution creates a blank model/controller in the engine and adds all
# functionality via a concern. To overwrite or add methods in the main app
# you simply create the same blank model/controller, include the same module
# and define your overwrites.
# You can even use the original methods by calling +super+.
# engine: app/controllers/myengine/my_controller.rb
module MyEngine
class MyController < ApplicationController
include MyEngine::Concerns::Controllers::MyController
end
end
# engine: app/concerns/myengine/controllers/my_controller.rb
module MyEngine::Concerns::Controllers::MyController
extend ActiveSupport::Concern
def index
end
end
# app: app/controllers/myengine/my_controller.rb
module MyEngine
class MyController < ApplicationController
include MyEngine::Concerns::Controllers::MyController
def index
end
end
end
# Source
# http://edgeguides.rubyonrails.org/engines.html#overriding-models-and-controllers