How to universally skip database touches when precompiling assets on Heroku How to universally skip database touches when precompiling assets on Heroku database database

How to universally skip database touches when precompiling assets on Heroku


add this to config/application.rb

config.assets.initialize_on_precompile=false                                                  

took me a while to hunt this down... adding it to config/environments/*.rb did NOT work

UPDATE: It doesn't work with rails 4


Heroku now makes a labs flag available that'll make the runtime environment available during compilation time, which means your app will be able to successfully connect to your DATABASE_URL database.

First you need to install the labs plugin:

$ heroku plugins:install http://github.com/heroku/heroku-labs.git

then enable the user-env-compile labs feature:

$ heroku labs:enable user-env-compile --app your-app-name


For me the problem is activerecord calling instantiate_observer in lib/active_record/railtie.rb:92. This will load the observers and the respective models. has_and_belongs_to_many then connects to the db.

I think I'll override this method when ENV["RAILS_ASSETS_PRECOMPILE"] is present, which is used by devise in the fix Bradley linked to.

EDIT: So this snippet fixed it for me:

namespace :assets do  # Prepend the assets:precompile_prepare task to assets:precompile.  task :precompile => :precompile_prepare  # This task will be called before assets:precompile to optimize the  # compilation, i.e. to prevent any DB calls.  task 'precompile_prepare' do    # Without this assets:precompile will call itself again with this var set.    # This basically speeds things up.    ENV['RAILS_GROUPS'] = 'assets'    # Devise uses this flag to prevent connecting to the db.    ENV['RAILS_ASSETS_PRECOMPILE'] = 'true'    # Prevent loading observers which will load the models which in turn may hit    # the DB.    module ActiveModel::Observing::ClassMethods      def instantiate_observers; end    end    # Prevent route drawing because certain gems might get called which will hit    # the DB.    class ActionDispatch::Routing::RouteSet      def draw; end    end  endend