rails db:migrate:resetできなかったのでrails db:resetした

## 結論から
dbをmigrateするときにエラーが出た場合、`rails db:migrate:reset`でDBリセットとmigrateを同時に行おうとすると失敗する場合がある。
migrationファイル内の実行順に問題がある可能性があるので、`rails db:reset`と`rails db:migrate`を分けて行うことで解決できる場合がある。

## 環境
Rails 5.1.2
Ruby 2.4.3

## 起こったこと
### migrationでエラー
rails tutorialを進めていてdbをmigrateしようとしたらこんなエラーが出ました。

```shell
$ rails db:migrate

== 20171229141042 CreateUsers: migrating ======================================
-- add_index(:users, :email, {:unique=>true})
   -> 0.0010s
-- create_table(:users)
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

SQLite3::SQLException: table "users" already exists: CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "email" varchar, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL)

...
```

userテーブルが既にあるのにつくろうとしている、と怒られています。

### reset:migrationでもエラー
そこで、 `rails db:migrate:reset`しようとしました。
（このコマンドは[7.4.3 実際のユーザー登録](https://railstutorial.jp/chapters/sign_up?version=5.1#sec-the_first_signup)の章で触れられています）

```shell
$ rails db:migrate:reset


Dropped database 'db/development.sqlite3'
Dropped database 'db/test.sqlite3'
Created database 'db/development.sqlite3'
Created database 'db/test.sqlite3'
== 20171229141042 CreateUsers: migrating ======================================
-- add_index(:users, :email, {:unique=>true})
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

SQLite3::SQLException: no such table: main.users: CREATE UNIQUE INDEX "index_users_on_email" ON "users" ("email")

...
```

またusersテーブルがないと怒られました。

処理の流れを見てみると、DBを削除して作り直した後にindexを追加しようとしてこけています。そしてusersテーブルを作成する処理が行われていません。

### migrationファイルを見てみる
migrationファイルを見てみると、原因がわかりました。

usersテーブルを作成する前にadd_indexしてしまっています。
rails tutorialを進める中で、migrationファイルを作る前にDBを色々操作したことが原因のようです。

```ruby
class CreateUsers < ActiveRecord::Migration[5.1]
  def change
    add_index :users, :email, unique: true
    create_table :users do |t|
      t.string :name
      t.string :email

      t.timestamps
    end
  end
end
```

こちらに書いてあることがヒントになりました。
https://stackoverflow.com/questions/33139275/error-on-migration-sqlite3sqlexception-no-such-table-main-users

上の記事のようにmigrationを修正しても良いのですが、[公式では推奨しないと書いてある](https://railsguides.jp/active_record_migrations.html#%E6%97%A2%E5%AD%98%E3%81%AE%E3%83%9E%E3%82%A4%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B)し、既にあちこちデータを触ってしまっていたので、わたしは下記の手順でエラーを解消しました。

### rails:db:resetしてみる
```shell
$ rails:db:reset


Dropped database 'db/development.sqlite3'
Dropped database 'db/test.sqlite3'
Created database 'db/development.sqlite3'
Created database 'db/test.sqlite3'
-- create_table("users", {:force=>:cascade})
   -> 0.0036s
-- create_table("users", {:force=>:cascade})
   -> 0.0021s
```
DBが削除、再作成され、usersテーブルが無事作られました。
このあとmigrationすると、usersテーブルが存在しているため問題なく成功します。


## rails db:resetとrails db:migration:resetの違い
`rails db:reset`と`rails db:migration:reset`はどちらも一旦全てのDBを 削除した後に作成し直すコマンドですが、下記の違いがあります。

### rails db:resetについて
`rails db:reset`はdb/schema.rbを元にDB作成します。db/migrate/**.rb は使われません。

Rails Guidesに下記のように記述があります。

>
bin/rails db:resetタスクは、データベースをdropして再度設定します。このタスクは、bin/rails db:drop db:setupと同等です。

>> 
このタスクは、すべてのマイグレーションを実行することと等価ではありません。このタスクでは現在のschema.rbの内容をそのまま使い回しているためです。マイグレーションをロールバックできなくなった場合には、bin/rails db:resetを実行しても復旧できないことがあります。スキーマダンプの詳細については、スキーマダンプの意義 セクションを参照してください。

[4.3 データベースをリセットする](https://railsguides.jp/active_record_migrations.html)

rails db:drop db:setupと同義ということで`rails db:setup`コマンドのドキュメント[(4.2 データベースを設定する)](https://railsguides.jp/active_record_migrations.html#%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B)を確認します。

* データベースの作成
* スキーマの読み込み
* シードデータを使用したデータベースの初期化

の３つの処理を実行すると書いてあります。

### rails db:migrate:resetについて
一方`rails db:migrate:reset`は、DBを削除した後に、db/migrate/**.rb を古い順から実行するそうです。
こちらは、migrateファイルを修正したときに、一度DBを削除した上で新たにmigrationを適用したい場合などに使うそうです。
ちなみにこちらは最新のRails Guidesにはこのコマンドが載っておらず[Rails 4系のドキュメント](http://railsdoc.com/references/rake%20db:migrate)にしか記載がありませんでした。

rails -Tで検索しても存在しません。

[英語版の5系のチュートリアル](https://www.railstutorial.org/book/sign_up#sec-successful_signups)でもこのコマンドを実行する指示があるのですが、実際は裏コマンド扱いなのでしょうか...？


## 終わりに
resetとmigrateを分けてコマンドを実行する方法は、データをあちこち触る開発初期などに使うといいかと思います。

エラーの根本的解決のためには、DBとmigrationファイルを確認して不整合を修正する必要があります。