gnikyt Code ramblings.

Precompiling assets in your Rails Engine

This will be a quick post to highlight an issue I had where I needed to precompile an asset file for my Rails engine that was not to be compiled with the other engine assets.

Recently, I added TinyMCE-Rails to Guts instead of rolling it in on its own. This allows me to abstract TinyMCE so it’s handled by the gem, and allows users to provide their own customizations and configurations.

Previously, I had a custom plugin that was hard-coded into TinyMCE as a simple button to allow users to add media from Guts into the editor. Now, using the gem, I need to make this a plugin, but I found issues getting the plugin file into production… it would never appear in shared/public when deploying the website via Capistrano after precompile ran. I was frustrated at first but knew it had to be a simple answer, I just needed to tell Rails about the file.

This was the directory structure:

app/
  assets/
    javascripts/
          guts/
              ...
        tinymce/
          plugins/
              guts_media/
                  plugin.js

I needed my tinymce/plugins/ folder to move into public/assets/tinymce generated by the TinyMCE gem.

After trial and error, the answer was simple and stupid… why didn’t I think of it before? I simply need to open my engine’s file and append my plugin path to assets.precompile provided by Rails. Here was the final working result (bottom of the file):

# Guts' module namespace
module Guts 
  # Guts' engine class
  class Engine < ::Rails::Engine
    # Isolate Guts routes
    isolate_namespace Guts
    
    # Autoload concerns
    config.autoload_paths << "#{config.root}/app/concerns"
    
    # Allow decorator usage for extending Guts
    config.to_prepare do
      Dir.glob("#{Rails.root}/app/decorators/*/guts/*_decorator*.rb").each do |c|
        require_dependency(c)
      end
    end
    
    # Load in our custom assets to precompile
    config.assets.precompile << "#{config.root}/app/assets/javascripts/tinymce/plugins/guts_media/plugin.js"
  end
end

I hope this helps anyone else stuck in a similar situation.