AssetPath with ActionController::Metal

At QFive we're building an API to serve our iOS application and throughout the site for ajax requests. Since our API only serves JSON we could slim down our controllers being used for the API to speed up requests as much as possible. In order to achieve this we've built a base controller for our API which inherits from ActionController::Metal instead of ActionController::Base. I was originally introduced to this idea in the book "Crafting Rails Applications" by Jose Valim.

One issue we've run into we've run into is related to the asset pipeline and serving assets from a custom asset host.

For example:

config/environments/production.rb

Example::Application.configure do
    config.action_controller.asset_host = "//static.example/com"
end

Typically the usage behind this in a rails application is masked, whenever you use image_tag the image will be routed to the asset host on its own behind the scenes. However since we're inheriting from ActionController::Base there is some work to be done. We'll need to include a couple of modules and ensure that the load hooks are loaded in our base controller, something that happens behind the scenes when inheriting from ActionController::Base.

class Api::V1::BaseController < ActionController::Metal
    include AbstractController::AssetPaths

    include ActionController::Redirecting
    include ActionController::Rendering
    include ActionController::Caching
    include ActionController::Renderers::All
    include ActionController::ConditionalGet
    include ActionController::ParamsWrapper
    include ActionController::MimeResponds

    ActiveSupport.run_load_hooks(:action_controller, self)
end

Of course, depending on what your application is using your mileage may vary. Our actual API BaseController looks something more like:

class Api::V1::BaseController < ActionController::Metal
    include AbstractController::AssetPaths
    include ActionController::Helpers

    include ActionController::Redirecting
    include ActionController::Rendering
    include ActionController::Caching
    include ActionController::Renderers::All
    include ActionController::ConditionalGet
    include ActionController::ParamsWrapper

    include ActionController::MimeResponds
    include ActionController::RequestForgeryProtection
    include AbstractController::Callbacks

    include ActionController::Instrumentation
    include ActionController::Rescue

    Rails.application.routes.default_url_options = ActionMailer::Base.default_url_options
    include Rails.application.routes.url_helpers

    append_view_path "#{Rails.root}/app/views"

    protect_from_forgery

    ActiveSupport.run_load_hooks(:action_controller, self)
end

Be sure to check out the rails ActionController::Base to see what else is included by default and tweak as you see fit.