自動デプロイ(capistrano)中に遭遇したNameErrorの話

ミナミ([@minami_nakasato](https://twitter.com/MinamiNakasato))です。

プログラミングスクールの課題でメル○カリのコピーアプリを制作しています。

その際Capistranoを使った自動デプロイに取り組んだのですが、どうにもエラーが止まらず難儀しました。

「どんなハイレベルな原因なのか」と悶えるも、冗談みたいに初歩的なミスだった話です。

# 作業環境

■Ruby 2.5.1

■Ruby on Rails 5.2.4

■本番環境
AWS(EC2)内に
webサーバー：nginx
アプリサーバー：Unicorn
データベース：MySQL
# 経緯

①「Rails new」コマンドでアプリを立ち上げる

②いったんCapistarnoの自動デプロイに成功。

③テーブルを用意するため「Rails g model」コマンドを実行。

生成されたのは以下のファイル

(1)モデルファイル

バリデーションとアソシエーションを記入。

(2)マイグレーションファイル

カラム名／データ型／not null制約

などなどを記入。

④「rails db:migrate」でテーブルを作成。

⑤ローカル環境で正常に動作する事を確認。

⑥自動デプロイのために「bundle exec cap production deploy」コマンドを実行。

すると、以下のエラーが表示される。

```ruby

00:13 unicorn:start
      01 $HOME/.rbenv/bin/rbenv exec bundle exec unicorn -c /var/www/frima/current/config/unicorn.rb -E deployment -D 
      01 master failed to start, check stderr log for details
#<Thread:0x00007fc1a0e12be8@/Users/lowgetsudo/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sshkit-1.20.0/lib/sshkit/runners/parallel.rb:10 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
	1: from /Users/lowgetsudo/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sshkit-1.20.0/lib/sshkit/runners/parallel.rb:11:in `block (2 levels) in execute'
/Users/lowgetsudo/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sshkit-1.20.0/lib/sshkit/runners/parallel.rb:15:in `rescue in block (2 levels) in execute': Exception while executing as ec2-user@3.115.193.237: bundle exit status: 1 (SSHKit::Runner::ExecuteError)
bundle stdout: Nothing written
bundle stderr: master failed to start, check stderr log for details
(Backtrace restricted to imported tasks)
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as ec2-user@3.115.193.237: bundle exit status: 1
bundle stdout: Nothing written
bundle stderr: master failed to start, check stderr log for details


Caused by:
SSHKit::Command::Failed: bundle exit status: 1
bundle stdout: Nothing written
bundle stderr: master failed to start, check stderr log for details

Tasks: TOP => unicorn:start
(See full trace by running task with --trace)
The deploy has failed with an error: Exception while executing as ec2-user@3.115.193.237: bundle exit status: 1
bundle stdout: Nothing written
bundle stderr: master failed to start, check stderr log for details


** DEPLOY FAILED
```

# 対応その１
「途中までは順調だったが、本番環境のunicornを起動する段階(unicorn:startのところ)でエラーになっておるな」

「[EC2インスタンスを再起動しよう](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-instance-reboot.html)」

「nginxを手動で再起動しよう」

```ruby
本番環境の当該アプリディレクトリで
$ sudo service nginx restart
```

「unicornを手動で再起動しよう」

```ruby
本番環境の当該アプリディレクトリで
$ bundle exec unicorn_rails -c config/unicorn.rb -E production -D
```

ふたたび自動デプロイコマンドを実行！

…失敗。

# 対応その２

「おれは先ほどローカルでテーブルを作る処理を行った」

「その後にエラーが起きたという事は、データベースに関係するエラーじゃろか」

「本番環境のデータベースを一度リセットしてみよう」

…以下のコマンドを順番に実行↓

①「git pull origin master」コマンドでGitHubのリモートリポジトリの中身をEC2に入れ込む。

②本番環境のDBを破壊

```
$ RAILS_ENV=production DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bundle exec rails db:drop
```

③本番環境にDBを構築

```
$ rails db:create RAILS_ENV=production
```

④本番環境にテーブルを生成

```
$ rails db:migrate RAILS_ENV=production
```

上記を実行後、再び自動デプロイのコマンドを実行！

…しかし、同じエラーがまだ続く。

# 対応その３

>
「そもそも、まずはエラーログを読むべきなんじゃないのか」

(ここでようやく気付く)

EC2に入り、ログを確認。

```/cd/var/www/自アプリ名/current/log/unicorn_stderr.log
I, [日付と時間 #10169]  INFO -- : Refreshing Gem list
bundler: failed to load command: unicorn (/var/www/frima/shared/bundle/ruby/2.5.0/bin/unicorn)
NameError: undefined local variable or method `belongs_to ' for #<Class:0x0000000004ddc5d0>
Did you mean?  belongs_to
```

という文言が表示される。

NameErrorの中身を訳すと、

>
『"belongs_to " なんて変数やメソッドはありませんよ』
『"belongs_to" の間違いじゃないのかね?』

「どういうこっちゃ！」

「”belongs_to”という文言、ということはモデルファイル内の記述ミスか」

「よく見ると、どうやらbelongs_toの後の 

" " (スペース)

に問題があるようだ」

確認してみると、

[訂正前]
<img width="180" alt="スクリーンショット 2019-12-09 17.51.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242355/1c71a445-572e-8953-5ad2-d38e6f5d6ae4.png">

普通の半角スペースに見えるが、一応すべてスペースを削除&再び追記してみる↓

[訂正後]
<img width="156" alt="スクリーンショット 2019-12-09 17.51.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242355/03c49a11-ce1e-6050-ef8c-08f5069e9f02.png">

すると、自動デプロイ成功！

# 原因
画像をよく見比べると、

**訂正前はただの半角スペース**

**訂正後は白い「・」がついた半角スペース**

となっている。

エラーの原因になったモデルを記入する際に、別のモデルファイルからコピー&ペーストしたが、その際に今回の**「よくない半角スペース」**になってしまったらしい。

そういえば前にも

半角の「" "」をコピペしたところ、

貼り付けると

全角の「” ”」になってしまいエラーが出たことがあった。

コピペはこういうエラーの原因になりがちなようだ。

よく確認しよう！

======================================
ミナミ([@minami_nakasato](https://twitter.com/MinamiNakasato))です。都内のベンチャー企業でwebデザイン／プログラミング／動画撮影や編集などをやっています。