How to start some initializers when executing Rails assets: precompile?

Background

I have an application that I recently upgraded to Rails 3.2.1 (from Rails 3.0.x) and redesigned JS and CSS assets to use the new asset pipeline. The app is hosted on Heroku using the Celadon Cedar Rack.

Application configuration

I save the specific application configuration in a YAML file called app_config.yml and load it into the global variable APP_CONFIG using the initializer:

# config/initializers/load_app_config.rb app_config_contents = YAML.load_file("#{Rails.root.to_s}/config/app_config.yml") app_config_contents["default"] ||= {} APP_CONFIG = app_config_contents["default"].merge( app_config_contents[Rails.env] || {} ).symbolize_keys 

Heroku asset compilation

Heroku supports the Rails resource pipeline built into the cedar stack. When you click an application in Heroku, it automatically calls rake assets:precompile on the server as a step in the deployment process. However, it does this in an isolated environment without access to the database or normal ENV-vars.

If the application is allowed to properly initialize during pre-compilation of the asset, an error occurs when connecting to the database. This is easily solved by adding the following to the application.rb file:

  # Do not load entire app when precompiling assets config.assets.initialize_on_precompile = false 


My problem

When initialize_on_precompile = false set, none of the initializers in config/initializers/* starts. The problem I am facing is that I need the APP_CONFIG variable to be available during resource precompilation.

How can I get load_app_config.rb to load during asset compilation without initializing the entire application? Can I do something with the group parameter passed to Rails :: Application.initialize!

+17
ruby-on-rails-3 heroku asset-pipeline
Feb 10 2018-12-12T00:
source share
5 answers

Rails only allows initializers to be registered in specific groups, but you need to use the Railtie API:

 # in config/application.rb module AssetsInitializers class Railtie < Rails::Railtie initializer "assets_initializers.initialize_rails", :group => :assets do |app| require "#{Rails.root}/config/initializers/load_config.rb" end end end 

You do not need to check if AppConfig is installed, as this will only run on the asset group.

And you can (and should) continue to use initialize_on_precompile = false . The load_config.rb initializer will be launched upon application initialization (since it is located in config/initializers ) and upon preliminary compilation without initialization (due to the above code).

+44
Oct 03
source share

Definitely check asset_sync on github. Or our Heroku dev center article on Using the CDN Host Resource with Rails 3.1 on Heroku .

Problems with environment variables have recently been resolved by the Heroku labs plugin, which makes your heroku config applications variables available at compile time. To enable this, read the user_env_compile plugin.

Besides. There is a pretty big performance improvement when using asset_sync , allowing your application to lazily compile assets in production or serve them, precompiled directly from application servers. However, I would say so. I wrote this.

  • With assets_sync and S3, you can precompile assets, meaning that all assets are ready for immediate maintenance on the host / CDN of the asset.
  • You may only need a package : assets in the .rb application for precompilation, memory preservation during production
  • Application servers NEVER fall under asset requests. You know, you can spend expensive time computing. Computational.
  • Best practices HTTP cache headers are set by default.
  • You can enable gzip automatic compression with one additional configuration
+7
Mar 07 2018-12-12T00:
source share

Here is what I came up with. For assets that need application configuration, I put 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'] .

During the preliminary compilation of the asset, it loads the application configuration, despite the fact that initialize_on_precompile set to false , and does this only once (which avoids the constant problems of overriding).

Yes, this is kludge, but many times better than embedding configurations in asset files.

+2
Feb 21 '12 at 12:35
source share

For Heroku I run the Asset Sync gem to store my files on a CDN to avoid Heroku hitting for still images. It works beautifully. I also initialize precompile false, but Asset Sync launches its own initializer so that you can put your code in it. https://github.com/rumblelabs/asset_sync

+1
Feb 11 '12 at 13:05
source share

Despite the fact that your intializer does not start when the assets are precompiled, you should still find that they start with Rails as normal, however, this will be in the first application hit, and not at the deployment stage.

I'm not quite sure you have a problem, but if you follow the Rails conventions, the deployment will work as expected.

0
Feb 11 2018-12-12T00:
source share



All Articles