Ruby on Rails
overloading Rails Engines Models and Controllers

This is a simple introduction on how to overload the default models and controllers in your Rails Engines.

For models, you will have to create an exact copy of that model in your own app/models folder. In the case of the Login Engine, most of the code inside the User model has been factored out into a different file. This is typically a good way to avoid repeating a lot of code (DRY).

For controllers, all you have to do is create a file with the same name as the controller you would like to overload in your own app/controllers folder. In the case of the Login Engine, simply create a file called user_controller.rb in app/controllers (or run the generator) and start adding new methods or overloading existing ones. Your new controller will inherit all the methods and properties of the existing Engine controller, while at the same time, using your newly created and overloaded methods. The same rule applies to views. Any new view that is created in your own local app/views folder will override the one that is in the Engine app/views folder.

More detailed information from James Adam:

For controllers, you just create a user_controller.rb (using Login_Engine as an example) in the usual place, like:

class UserController < ApplicationController

def new_method
# whatever
end

def existing_method # this will be used in preference of the one in the login engine end

end

You can also intercept calls using standard Ruby techniques such as alias_method.

alias_method :proper_login, :login

def login
  do_stuff_here
  proper_login
end

With model objects, you need to copy the whole object from an Engine. In the case of the LoginEngine, the only significant entry is the inclusion of the LoginEngine::AuthenticatedUser module, so you can actually just run script/generate model User and then add in that line yourself, along with anything new that you need.

Another method for model objects is to include the following in the custom model file:

require_dependency "#{RAILS_ROOT}/vendor/plugins/ENGINE/app/models/MODEL.rb"

The engines system then calls the custom file which in turn calls the engine’s file. The “require_dependency” method ties the two files together resulting in the proper development behavior of being able to change either file and see the result without restarting.

The magic is performed by the Engines plugin, which will merge your changes into the LoginEngine controller (and any helpers too), andwill load your custom model rather than the engine one.