Herokuへのデプロイ時に苦労した話

昨日完成したTodoアプリをHerokuにアップしました!

その際2箇所でつまづいたので、記録しておきます。

pg gemがインストールできない

HerokuではSQLiteがサポートされていないのでPostgreSQLを使います。

sqlite3 gemをproduction環境で使わないように、
そしてpg gemをproduction環境で使うようにgemfileを編集し、bundle installしたところ

Building native extensions.  This could take a while...
ERROR:  Error installing pg:
    ERROR: Failed to build gem native extension.
(略)
Can't find the 'libpq-fe.h header

libpq-fe.h が見つからない、というエラーが出ました。

このエラーの処理は

$ sudo yum install postgresql-devel

で解決。
(yumというのを使ってPostgreSQLをインストールするということらしいです)


(本筋と関係なし)

無事にpg gemもインストールできたのでherokuにpushしました。
デプロイしたページにアクセスすると……




We're sorry, but something went wrong

ああ……

色々調べた結果、

「production環境でrails_12factorというgemを有効にする必要がある」

という情報にたどり着き、gemfileに追記したのですが
調べ直したところこの情報はRailsチュートリアル第4版から、つまりRails5になってからは記載が無くなった情報なので、今はもう必要ないのかもしれません。

本題は次のエラーです。

Userテーブル作成時のマイグレーションファイルを削除してしまった

heroku logsで確認してみると、rootページへのGETリクエストは成功しているけどその後移動するログインページで500エラーが出ていました。

データベースの問題じゃないかと思ってdb:migrateを実行してみると……

$ heroku run rake db:migrate
Running rake db:migrate on ⬢ rocky-beyond-45744... up, run.9472 (Free)
   (0.8ms)  SELECT pg_try_advisory_lock(2653661978130648765)
   (1.3ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
Migrating to AddUserRefToTasks (20180827040204)
   (0.8ms)  BEGIN
== 20180827040204 AddUserRefToTasks: migrating ================================
-- add_reference(:tasks, :user, {:foreign_key=>true})

  (略)

   (1.4ms)  ROLLBACK
   (5.0ms)  SELECT pg_advisory_unlock(2653661978130648765)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::UndefinedTable: ERROR:  relation "users" does not exist

(略)

Caused by:
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR:  relation "users" does not exist

usersテーブルが存在しない、というエラーが出ました。

ん?と思ってdb/migrateを確認すると、Userモデルを作成したときのマイグレーションファイルが無い。

Devise導入の際にrails g devise UserでUserモデルが作成できているのかわからず試行錯誤したのですが、
どうやらその時に作成されたマイグレーションファイルを削除してしまったようです。

解決方法

joppot.info

この記事を参考に以下の処理をしました。

状況

削除してしまったマイグレーションファイルのIDを調べます

$ bundle exec rake db:migrate:status
database: 省略/db/development.sqlite3

 Status   Migration ID    Migration Name
--------------------------------------------------
   up      20180823030402  Create tasks
   up     ★20180826083613  ********** NO FILE **********
   up      20180827040204  Add user ref to tasks
   up      20180829041636  Add row order to tasks

NO FILE になっているIDが今回間違えて削除してしまったマイグレーションファイルです。

そして、Statusがupになっているマイグレーションファイルはデータベースに取り入れられているものです。

本番環境でマイグレーションを実行した時に、★20180826083613のファイルが存在しないので冒頭のエラーが出てしまった、という状況ですね。

対処方法

プロジェクトのdb/migrateディレクトリに移動します

$ cd db/migrate

ここで、先程確認した間違えて消してしまったファイルと同じIDのマイグレーションファイルを作成します。

$ touch マイグレーションID_ファイル名.rb

今回の場合だと

$ touch 20180826083613_devise_create_users.rb

になります。

作成したマイグレーションファイルに内容を書き込みます。
私の場合はDevise練習用に作成した別のプロジェクトがあったのでそこから引っ張ってきました。

# frozen_string_literal: true

class DeviseCreateUsers < ActiveRecord::Migration[5.2]
  def change
    create_table :users do |t|
      ## Database authenticatable
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""
 
(略)

    add_index :users, :email,                unique: true
    add_index :users, :reset_password_token, unique: true
    # add_index :users, :confirmation_token,   unique: true
    # add_index :users, :unlock_token,         unique: true
  end
end

これで間違えて削除してしまったマイグレーションファイルが復活した状態になったので

$ git add .
$ git commit
$ git push heroku master

でherokuにプッシュし、再度 本番環境でdb:migrate

$ heroku run rake db:migrate

うまくいきました!
これでアプリケーションの作成からHerokuへのデプロイまでをひと通り完了することができました。
次に何をするか考えようと思います。

参考リンク

Herokuへのデプロイでつまづいたことまとめ

libpq-fe.h が見つけられない。

railsのrakeのmigrationファイルを削除しNO FILEとstatusに出た時の対処 – joppot