読者です 読者をやめる 読者になる 読者になる

Apartment を使った Rails アプリを Heroku にデプロイできない

マルチテナント用の gem である apartment を使っている Rails アプリを、 Heroku に push すると下記のエラーが発生した。

Preparing app for Rails asset pipeline
       Running: rake assets:precompile
       rake aborted!
       Gem::LoadError: Specified 'sqlite3' for database adapter, but the gem is not loaded. Add `gem 'sqlite3'` to your Gemfile (and ensure its version is at the minimum required by ActiveRecord).
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/activerecord-4.1.0/lib/active_record/connection_adapters/connection_specification.rb:190:in `rescue in spec'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/activerecord-4.1.0/lib/active_record/connection_adapters/connection_specification.rb:187:in `spec'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/activerecord-4.1.0/lib/active_record/connection_handling.rb:50:in `establish_connection'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/apartment-0.24.3/lib/apartment/adapters/abstract_adapter.rb:82:in `block in process_excluded_models'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/apartment-0.24.3/lib/apartment/adapters/abstract_adapter.rb:81:in `each'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/apartment-0.24.3/lib/apartment/adapters/abstract_adapter.rb:81:in `process_excluded_models'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/apartment-0.24.3/lib/apartment/database.rb:18:in `init'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/apartment-0.24.3/lib/apartment/railtie.rb:31:in `block in <class:Railtie>'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/activesupport-4.1.0/lib/active_support/callbacks.rb:438:in `instance_exec'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/activesupport-4.1.0/lib/active_support/callbacks.rb:438:in `block in make_lambda'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/activesupport-4.1.0/lib/active_support/callbacks.rb:184:in `call'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/activesupport-4.1.0/lib/active_support/callbacks.rb:184:in `block in simple'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/activesupport-4.1.0/lib/active_support/callbacks.rb:185:in `call'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/activesupport-4.1.0/lib/active_support/callbacks.rb:185:in `block in simple'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/activesupport-4.1.0/lib/active_support/callbacks.rb:86:in `call'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/activesupport-4.1.0/lib/active_support/callbacks.rb:86:in `run_callbacks'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/actionpack-4.1.0/lib/action_dispatch/middleware/reloader.rb:83:in `prepare!'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/actionpack-4.1.0/lib/action_dispatch/middleware/reloader.rb:55:in `prepare!'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/railties-4.1.0/lib/rails/application/finisher.rb:52:in `block in <module:Finisher>'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/railties-4.1.0/lib/rails/initializable.rb:30:in `instance_exec'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/railties-4.1.0/lib/rails/initializable.rb:30:in `run'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/railties-4.1.0/lib/rails/initializable.rb:55:in `block in run_initializers'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/railties-4.1.0/lib/rails/initializable.rb:54:in `run_initializers'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/railties-4.1.0/lib/rails/application.rb:288:in `initialize!'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/config/environment.rb:5:in `<top (required)>'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/activesupport-4.1.0/lib/active_support/dependencies.rb:247:in `require'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/activesupport-4.1.0/lib/active_support/dependencies.rb:247:in `block in require'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/activesupport-4.1.0/lib/active_support/dependencies.rb:232:in `load_dependency'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/activesupport-4.1.0/lib/active_support/dependencies.rb:247:in `require'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/railties-4.1.0/lib/rails/application.rb:264:in `require_environment!'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/railties-4.1.0/lib/rails/application.rb:367:in `block in run_tasks_blocks'
       /tmp/build_4f21ff1d-af6a-46cb-ba2e-935e4be9cdd8/vendor/bundle/ruby/2.0.0/gems/sprockets-rails-2.1.3/lib/sprockets/rails/task.rb:55:in `block (2 levels) in define'
       Tasks: TOP => environment
       (See full trace by running task with --trace)
 !
 !     Precompiling assets failed.
 !

 !     Push rejected, failed to compile Ruby app

Rails 初期化時に apartment の初期化を行っており、 database.yml に書かれている production 環境のアダプタを読み込もうとしてエラーが発生していた。 SQLite のアダプタを読み込もうとしたのが原因みたい。

Heroku に push したとき、 Heroku Postgres を使うように database.yml が自動で書き換わるんだけど、 Rails 初期化のタイミングではまだ書き換わっていなかったようだ。

database.yml で

production:
  adapter: postgresql
  host: HerokuPostgresホスト名
  port: 5432
  username: ユーザー名
  password: パスワード
  database: データベース名

という風に、SQLite ではなく PostgreSQL のアダプタを使うように書いておけば回避できた。