Engines vs Generators

Engines could be considered in many ways the natural successor to Rails’ generators:

  • Both are mechanisms for packaging up disparate groups of files which must be placed throughout your whole application directory structure
  • Both provide controllers, models, libraries and views, along with schema information, tests and helpers to be used throughout your application’s code.

Generators: Scaffolding for the masses?

However, there are serious problems with generators: the generated static code is then often directly modified to suit the specific individual needs of the application. This makes it problematic to propagate bug-fixes and new features to applications which have used a given generator - it is impossible to tell which parts of the application can be safely overwritten by updated files, and which files have been customised.

Going through the operations performed when re-running a generator is a tedious and developer-intensive task. Wasn’t developing in Rails meant to be done with “joy”?

In a nutshell, generators are fine for quickly adding a bunch of code to your application, but that code quickly becomes impossible to manage between multiple applications.

From the developer’s point of view, generators can also be painful to maintain; all files must be distributed in a format to be processed by ERb; each time the developer wants to update their generator they must generate the code, make the changes and then translate those changes back into the ERb-formatted file.

Engines: a fresh approach

The engines plugin extends Rails’ own minimal plugin system just enough to allow you to include in your plugin almost any type of file you might find in a regular Rails application: controllers, views, helpers, libraries, models, schemas, tests, stylesheets and javascripts… anything you can think of, essentially.

These files are contained within a single directory inside /vendor/plugins, completely isolating them from the rest of your application and therefore making it trivial to update to new versions.

It is still crucial that you as the developer be allowed to alter the behaviour of this packaged code to suit the individual needs of your application. With this in mind, the Engines plugin allows you to override the behaviour of engine code in a simple and clear way:

  • single views can be provided which are automatically used instead of those provided with the engine
  • controller actions can be overridden individually in your application, isolating your custom code from the underlying default implementation
  • model and library code is normally provided as a ruby Module, making it simple to include in your own custom Models

Developing an engine is a much more natural process, compared to creating generators - there is no ‘ERb translation step’, and changes to an engine can be made and committed in one application and then propagated to another application with no intermediate stages. Engine code looks exactly like normal Rails application code, making it intutive to skim when you are examining an engine’s behaviour.