HerokuでのアプリのデプロイでMySQLを使用してみた。

## はじめに
Railsで作成したアプリをHerokuへデプロイしようと思ったのですが、DBをMySQLで作成していました。
HerokuではDBの初期設定はPostgresqlになっているので変更処理を行い、デプロイするまでの流れを備忘録として残します。


## 前提条件
・作成したアプリのソースコードをGitHubで管理している
・Herokuのアカウントを所有し、クレジットカード情報を登録済み
・Heroku CLI がインストール済み

```
$ heroku -v
heroku/7.35.1 darwin-x64 node-v12.13.0
```


## デプロイまでの流れ

#### 1.Herokuへログイン
まずはHerokuにログインをします。`heroku login`コマンド入力でエンターを押すとログイン画面が表示されますので、登録済みのメールアドレスとパスワードを入力します。

```
$ heroku login
heroku: Press any key to open up the browser to login or q to exit:   #エンター押す
Opening browser to https://cli-auth.heroku.com/auth/cli/browser/3c35ddf6-f0a6-4911-9bd8-e9472b963bb8
Logging in... done
Logged in as [メールアドレス]
```

#### 2.Heroku上でアプリを作成
作成したRailsアプリのディレクトリに移動し、Heroku上にアプリを作成します。アプリ名は小文字か数字かダッシュを含む等の条件があり、アンダーバーを含めるとエラーになりました。あとアプリ名はユニークが必須なので同名が存在すると同じくエラーになります。
私は作成したRailsアプリ名に`_`が含まれていましたので、Herokuのアプリには`-`に変更しましたが、問題はありませんでした。

```
$ cd [アプリ名]
$ heroku apps:create [アプリ名]
Creating ⬢ [アプリ名]... done
https://[アプリ名].herokuapp.com/ | https://git.heroku.com/[アプリ名].git

# [アプリ名]にアンダーバー等を含めると以下のようにエラーが生じます。
Creating ⬢ [アプリ名]... !
 ▸    Name must start with a letter, end with a letter or digit and can only contain lowercase letters, digits, and dashes.

# [アプリ名]がユニークでないとエラーが生じます。
Creating ⬢ [アプリ名]... !
 ▸    Name [アプリ名] is already taken
```

#### 3.リモートリポジトリの確認
作成したアプリがリモートリポジトリの一覧表示に入っているか確認します。次のように表示されていればOKです。

```
$ git remote -v
heroku  https://git.heroku.com/[アプリ名].git (fetch)
heroku  https://git.heroku.com/[アプリ名].git (push)
origin  https://github.com/[GitHubオーナー名]/[アプリ名].git (fetch)
origin  https://github.com/[GitHubオーナー名]/[アプリ名].git (push)
```

#### 4.MySQLを追加
cleardbというクラウド上でMysqlを使うためのサービスがあります。プランはがいくつかありますが、igniteは無料です。

```
$ heroku addons:create cleardb:ignite
Creating cleardb:ignite on ⬢ [アプリ名]... free
Created cleardb-objective-20233 as CLEARDB_DATABASE_URL
Use heroku addons:docs cleardb to view documentation
```

#### 5.MySQLの接続設定を修正
HerokuのアプリにDB情報の環境変数を設定します。

```
$ heroku config
=== [アプリ名] Config Vars
CLEARDB_DATABASE_URL: mysql://[ユーザー名]:[パスワード]@[ホスト名]/[データベース名]?reconnect=true

$ heroku config:add DB_NAME='[データベース名]'
$ heroku config:add DB_USERNAME='[ユーザー名]'
$ heroku config:add DB_PASSWORD='[パスワード]'
$ heroku config:add DB_HOSTNAME='[ホスト名]'
$ heroku config:add DB_PORT='3306'
$ heroku config:add DATABASE_URL='mysql2://[ユーザー名]:[パスワード]@[ホスト名]/[データベース名]?reconnect=true'

$ heroku config
=== [アプリ名] Config Vars
CLEARDB_DATABASE_URL:     mysql2://[ユーザー名]:[パスワード]@[ホスト名]/[データベース名]?reconnect=true
DATABASE_URL:             mysql2://[ユーザー名]:[パスワード]@[ホスト名]/[データベース名]?reconnect=true
DB_HOSTNAME:              [ホスト名]
DB_NAME:                  [データベース名]
DB_PASSWORD:              [パスワード]
DB_PORT:                  3306
DB_USERNAME:              [ユーザー名]
LANG:                     en_US.UTF-8
RACK_ENV:                 production
RAILS_ENV:                production
RAILS_LOG_TO_STDOUT:      enabled
RAILS_SERVE_STATIC_FILES: enabled
SECRET_KEY_BASE:          [シークレットキー]
```

#### 6.デプロイ
ローカルリポジトリをHeorkuへプッシュ（デプロイ）します。

```
$ git push heroku master
```
Heroku上でマイグレーションを実行します。

```
$ heroku rake db:migrate
```
ブラウザでアプリケーションを開きます。

```
$ heroku open
```

無事アプリが立ち上がりました。
<img width="1247" alt="スクリーンショット 2020-01-28 19.28.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438093/9e13a94e-cc2e-6523-4e9f-d711f7acec69.png">

ですが実装した機能の挙動を確認すると……
<img width="553" alt="スクリーンショット 2020-01-28 19.32.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438093/1684f708-d47e-919c-b80c-32fc39b3a2ae.png">

#### 7.エラー修正
エラーログを確認してみます。

```
$ heroku logs -t
2020-01-28T11:14:15.961613+00:00 heroku[router]: at=info method=GET path="/users/sign_up" 
・
・
2020-01-28T11:14:16.843615+00:00 app[web.1]: F, [2020-01-28T11:14:16.843544 #4] FATAL -- : [531d4104-748b-469f-bfdb-c44e4058016b] ActionController::RoutingError (uninitialized constant RegistrationsController):
```
定義した`RegistrationsController`を読み込めないらしく、ここに原因があるとわかりました。ローカルではこのようなエラーは再現されませんでしたので、最初困惑しました。

しかし`app/controllers`のディレクトリ配下に確かに`Registrations_controller`がありません。探してみると`vendor`ディレクトリ配下にありました。たぶん作成時に設置場所を間違えていたのだと思います。
`Registrations_controller`を`app/controllers`内に移動させて、再度herokuへアップしました。

```
$ git push heroku master
$ heroku rake db:migrate
$ heroku open
```

無事実装した機能の挙動確認が取れました。デプロイ完了です。


## 参考記事
https://devcenter.heroku.com/articles/cleardb
https://elements.heroku.com/addons/cleardb