【Rails × Heroku】HerokuでYouTube APIを実行しようとした時のエラー

# 概要
今回、個人開発のアプリをHerokuでデプロイしrakeタスクでYouTube APIを叩こうとした際にエラーが出たので、その原因と解決方法をまとめました。

# 環境
Ruby : 2.6.6
Rails : 6.0.3
Heroku : 7.59.1
MySQL : 8.0.26
OS : macOS Catalina

# 発生したエラー

```
$ heroku run rake youtube_task:youtube_video_save 

Running rake youtube_task:youtube_video_save on ⬢ mukinator... up, run.8232 (Free)
rake aborted!
NoMethodError: undefined method `[]' for nil:NilClass
/app/lib/tasks/youtube_task.rake:11:in `block (2 levels) in <main>'
/app/vendor/bundle/ruby/2.6.0/gems/rake-13.0.6/exe/rake:27:in `<top (required)>'
/app/vendor/bundle/ruby/2.6.0/gems/bundler-2.2.21/lib/bundler/cli/exec.rb:63:in `load'
/app/vendor/bundle/ruby/2.6.0/gems/bundler-2.2.21/lib/bundler/cli/exec.rb:63:in `kernel_load'
/app/vendor/bundle/ruby/2.6.0/gems/bundler-2.2.21/lib/bundler/cli/exec.rb:28:in `run'
/app/vendor/bundle/ruby/2.6.0/gems/bundler-2.2.21/lib/bundler/cli.rb:474:in `exec'
/app/vendor/bundle/ruby/2.6.0/gems/bundler-2.2.21/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/app/vendor/bundle/ruby/2.6.0/gems/bundler-2.2.21/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
/app/vendor/bundle/ruby/2.6.0/gems/bundler-2.2.21/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
/app/vendor/bundle/ruby/2.6.0/gems/bundler-2.2.21/lib/bundler/cli.rb:30:in `dispatch'
/app/vendor/bundle/ruby/2.6.0/gems/bundler-2.2.21/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
/app/vendor/bundle/ruby/2.6.0/gems/bundler-2.2.21/lib/bundler/cli.rb:24:in `start'
/app/vendor/bundle/ruby/2.6.0/gems/bundler-2.2.21/exe/bundle:49:in `block in <top (required)>'
/app/vendor/bundle/ruby/2.6.0/gems/bundler-2.2.21/lib/bundler/friendly_errors.rb:128:in `with_friendly_errors'
/app/vendor/bundle/ruby/2.6.0/gems/bundler-2.2.21/exe/bundle:37:in `<top (required)>'
/app/bin/bundle:113:in `load'
/app/bin/bundle:113:in `<main>'
Tasks: TOP => youtube_task:youtube_video_save
(See full trace by running task with --trace)

```

エラーログを見ると

```
NoMethodError: undefined method `[]' for nil:NilClass
```

何かがnilになっていることがわかり、その場所が

```
/app/lib/tasks/youtube_task.rake:11:in `block (2 levels) in <main>'
```
と書いてあるので該当の箇所を見てみると、

```app/lib/tasks/youtube_task.rake
youtube.key = Rails.application.credentials.youtube[:youtube_api_key]
```

このコードでエラーが起きてたみたいです。
ここのコードではYouTube APIを使うためにAPI keyを渡しているのですがうまく渡せていなかったようです。

# 原因
今回の自分のアプリではAPI keyを管理する方法としてrailsの機能として備わっている「credentials」を使っています。
今回はcredentialsについての記事ではないため説明は省略します。
詳しくは以下の記事を参考にしてください。

https://qiita.com/gyu_outputs/items/92c4a2a2f96edb10e298

credentialsについて簡単に言うと、公開したくない情報など（今回で言えばYouTube APIのAPI key）を管理するための機能です。
秘密にしておきたい情報を「credentials.yml.enc」に書いて管理するのですが、これには**master.key**が必要です。
master.keyがないとcredentials.yml.encの中の読み書きができないわけです。

ですが今回、このmaster.keyをHerokuに設定していませんでした。
そのためcredentials.yml.encの中にあるAPI keyを取得できないため youtube.key が nil となりエラーが起きたと考えています。

.gitignoreにmaster.keyが記述されているのでHerokuには渡らないですよね。

```アプリ名/.gitignore
/config/master.key
```

# 解決方法
原因はわかりました。
Herokuにmaster.keyを設定してあげれば動きそうなので設定しましょう。
master.keyを環境変数として設定するのですが、やり方として２つあります。

1. Herokuのサイトから設定する方法
2. ターミナルから設定する方法

どちらか片方で大丈夫なので、お好きな方で設定してください。

## Herokuのサイトから設定する方法
### 1. Herokuのサイトにログインする
[サイト](https://dashboard.heroku.com/)にアクセスしてログインしましょう。

### 2. 対象のアプリを選択
対象のアプリを選択し、上のタブから「settings」を選択する
![スクリーンショット 2021-11-04 10.57.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1629690/6a957a1e-21b7-3f20-5f82-64adb49f05fa.png)

### 3. Config Varsの「Reveal Config Vars」をクリック
![スクリーンショット 2021-11-04 10.57.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1629690/3f4787ec-751e-a5b7-7dc9-39f57c6993b8.png)

### 4. 「KEY」と「VALUE」をそれぞれ設定し保存
今回はmaster.keyを設定するので「KEY」は「MASTER_KEY」のように分かりやすい名前がいいと思います。
「VALUE」はそれぞれの値を入れてください。
![スクリーンショット 2021-11-04 11.18.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1629690/2bbff298-f29f-469d-628f-8f8eea4b809e.png)

これでサイトからmaster.keyを環境変数として設定することができました。


## ターミナルから設定する方法
もう一つのやり方、ターミナルを使った設定方法です。

アプリがあるディレクトリに移動します。
今設定されている環境変数を確認します。
以下のコマンドで設定されている環境変数(KEY と VALUE)が表示されます。

```
$ heroku config
```
設定のやり方は以下の通りです。

```
$ heroku config:set 顕教変数名=値
```
具体的なコマンドは以下のようになると思います。
＊「=」の前後にスペースが入ってしまうと設定できないので注意してください。

```
$ heroku config:set MASTER_KEY=`cat config/master.key`
```
環境変数として設定したので確認してみましょう。

```
$ heroku config
```
上記のコマンドで今設定した環境変数（master.key）が表示されていれば設定の完了です。

# 再度YouTube APIを叩いてみる
master.keyをHerokuに設定したのでもう一度rakeタスクを実行してYouTube APIを叩いてみましょう。

```
$ heroku run rake youtube_task:youtube_video_save 
```
再度実行したらちゃんとrakeタスクが実行され動画が取得できました👏

# 今回のエラーに遭遇して思ったこと
ローカルでは動いているのに、Herokuにデプロイしてcredentials関係でエラーが出たらmaster.keyも視野に入れて考えてみると良いと思います。

# 最後に
最後まで読んでいただきありがとうございます。
少しでも役に立ったなら幸いです。

# おまけ
今回作ったアプリの紹介

**「MUKINATOR」（ムキネイター）**

https://mukinator.com/

日常で生まれる悩みや不安を全て筋トレで解決するアプリです。
使ってもらえると嬉しいです。

Qiita記事

https://qiita.com/takemuu/items/7dd6297df61d1a567bc6