Engines have been around Rails for years but it wasn't until the recent 2.3 release that Rails officially supported Engines. So what is an Engine? An Engine is a Rails plugin with full MVC capabilities. In essence, that means your Engine has an app directory with helpers, controllers, models and views just like a standard Rails application. You add an engine to vendor/plugins or through config.gem in your application, just like a plugin, but additionally its app directory is effectively overlaid on top of your application's app directory.

Let's spelunk through the code:

rails-2.3.2/lib/rails/plugin/loader.rb

def configure_engines
          if engines.any?
            add_engine_routing_configurations
            add_engine_controller_paths
            add_engine_view_paths
          end
        end

        def add_engine_routing_configurations
          engines.select(&:routed?).collect(&:routing_file).each do |routing_file|
            ActionController::Routing::Routes.add_configuration_file(routing_file)
          end
        end

        def add_engine_controller_paths
          ActionController::Routing.controller_paths += engines.collect(&:controller_path)
        end

        def add_engine_view_paths
          # reverse it such that the last engine can overwrite view paths from the first, like with routes
          paths = ActionView::PathSet.new(engines.collect(&:view_path).reverse)
          ActionController::Base.view_paths.concat(paths)
          ActionMailer::Base.view_paths.concat(paths) if configuration.frameworks.include?(:action_mailer)
        end

For each engine, we add any routes, any controllers and any views. Additionally, the directories within app will be added to the global LOAD_PATH, as with a normal application. Note that engines are processed in order exactly like plugins: alphabetically or based on the order they are listed in config/environment.rb.

There are some limitations you should be aware of:

So while Engines do have some limitations to be aware of, they do fill a valuable niche; engines provide a good framework for building full-stack generic application functionality. ActiveScaffold is one example of a Rails plugin that would be an excellent choice to rewrite as an Engine.

comments powered by Disqus