How can I run SOME initializers when doing a Rails assets:precompile?
Rails lets you register initializers only in certain groups, but you need to use the Railtie API:
# in config/application.rbmodule AssetsInitializers class Railtie < Rails::Railtie initializer "assets_initializers.initialize_rails", :group => :assets do |app| require "#{Rails.root}/config/initializers/load_config.rb" end endend
You don't need to check if AppConfig is defined since this will only run in the assets group.
And you can (and should) continue to use initialize_on_precompile = false
. The load_config.rb initializer will be run when initializing the app (since it's in config/initializers
) and when pre-compiling without initializing (because of the above code).
Definitely check out asset_sync on github. Or our Heroku dev centre article on Using a CDN asset Host with Rails 3.1 on Heroku.
The issues with environment variables have recently been solved by a Heroku labs plugin, that makes your application's heroku config
variables accessible during compilation time. To enable this, read about the user_env_compile plugin.
Also. There is quite a big performance improvement in using asset_sync vs letting your application lazily compile assets in production or serving them precompiled directly off your app servers. However I would say that. I wrote it.
- With asset_sync and S3 you can precompile assets meaning all the assets are there ready to be served on the asset host / CDN immediately
- You can only require the :assets bundle in application.rb on precompile, saving memory in production
- Your app servers are NEVER hit for asset requests. You can spend expensive compute time on, you know. Computing.
- Best practice HTTP cache headers are all set by default
- You can enable automatic gzip compression with one extra config
Here's what I came up with. In the assets that need app configuration, I place this line at the very beginning:
<% require "#{Rails.root}/config/initializers/load_config.rb" unless defined?(AppConfig) %>
... and add .erb
to the file name, so that video_player.js.coffee
becomes video_player.js.coffee.erb
. Then I can safely use AppConfig['somekey']
afterwards.
During the asset pre-compilation, it loads app config despite the initialize_on_precompile
set to false
, and does it only once (which avoids constant redefinition issues).
Yes, it's a kludge, but many times nicer than embedding configs in asset files.