iprog.com

Errors when precompiling assets in Rails 4.0

Rails 4 now always loads initializers and the database configuration before precompiling assets. Depending on your deployment environment, this may cause errors.

For example, not finding database.yml:

Could not load database configuration. No such file - /apps/some_app/releases/20130703220638/config/database.yml

In Rails 3, this was solved with:

1config.assets.initialize_on_precompile = false

However, this configuration option no longer exists in Rails 4. One workaround is to pass a dummy database init string to rake assets:precompile:

1DATABASE_URL=postgresql://user:pass@127.0.0.1/dbname

Be sure to replace postgresql with your database adapter name if using something other than Postgres.

A complete example:

1bundle exec rake RAILS_ENV=production DATABASE_URL=postgresql://user:pass@127.0.0.1/dbname assets:precompile

With Capistrano’s assets handling, you can just set :asset_env:

1set :asset_env, "RAILS_GROUPS=assets DATABASE_URL=postgresql://user:pass@127.0.0.1/dbname"
tags: rails4, capistrano, rails

by snackycracky

thx that helped.

by Serhii Khoma

that didnt help

PG::ConnectionBad: could not connect to server: Connection refused
Is the server running on host “127.0.0.1” and accepting
TCP/IP connections on port 5432?

by tm

this was written back when rails 4.0 was current. is that the version you’re running?

if you’re using a more recent version, rails now defers connecting to the database until the database is actually accessed. by default, assets:precompile does not trigger database use, so should run fine. a quick test on rails 5.2 confirms that this is indeed true.

check your initializers (and possible rake tasks, if you’ve done anything fancy there) for code that triggers premature database usage and remove it, or somehow make it deferable or otherwise conditional.

by Alexander

How can one make the code deferable? My issue is registering a custom ActiveRecord type. There is no database access, just type registration. But it still tries to reach database.

by tm

when extending activerecord, it’s pretty easy to end up triggering a schema load, which might be why it’s trying to reach the database.

since custom type registrations are unlikely to be needed during asset precompilation, one trick is to use an ENV var to skip a troublesome initializer. for example:

1unless ENV['SKIP_CUSTOM_TYPE']=='skip'
2  # register your custom type here
3end

then precompile with:

1rails assets:precompile SKIP_CUSTOM_TYPE=skip
2# or:
3env SKIP_CUSTOM_TYPE=skip rails assets:precompile