Ruby on Rails 削除関連まとめ

# はじめに
アプリ作成中に、「なんか気に入らないから1回削除して一から作り直したい」と思ったことはありませんか？
私はよくあります。そんな時に必要になる操作をまとめました。
すでによく作りこんでいる場合は、削除して作り直すわけにもいきませんから変更の方法を探してみてください。

## 自分の環境
- ruby 2.6.5
- Rails 6.0.2
- macOS Catalina 10.15.3

# アプリの削除
アプリの削除をするにはアプリのフォルダを削除すればいいのですが、その前にデータベースを削除しておきましょう。（まだ`rails db:create`などでデータベース作成をしていない場合は必要ありません。）

削除しなくても問題ないですが、PC内にずっとデータベースが残ってしまいますし、いつかそのデータベースが原因で不具合が起きる可能性があります。

アプリケーションフォルダ内で以下コマンドを実行。

```
$ rails db:drop
```

これでデータベースが削除されます。
そのあとは、以下コマンドでアプリフォルダを削除してもいいですし、ゴミ箱へと放り込んでもいいでしょう。

```
$ cd .. (1つ上のフォルダへ)
$ rm -rf [アプリ名]
```

ちなみに上記削除コマンドの意味は、

- rm = 削除するというコマンド
- -rf = ファイルでなくフォルダを削除するよという「-r」と削除官僚のメッセージ表示はいらないよという「-f」の組み合わせ

## 先にアプリを削除してしまった場合
データベースのみが残り、アプリがないためデータベースの削除ができません。

コンソールからsqlite3やmysqlに直接ログインし、データベースを消去しましょう。
「sqlite3 ログイン」や「mysql データベース　削除」などで調べてみてください。

もしくは、ちょっと裏技っぽいのですが、まったく同じ名前のアプリをrails newしてからrails db:dropしてもいいです。（アプリの名前とデータベースの名前が一致しているため。）

# コントローラの削除
アプリケーションフォルダ内で以下のコマンドを実行します。

```
$ rails destroy controller [削除したいコントローラ名]
```

作成の際の`rails generate`はrails gと省略できますが、destroyは出来ません。

## ルーティングの削除
ルーティングは自分でconfig/routes.rbの該当部分を消しましょう。

# モデルの削除
マイグレーションを実行する前か後かで操作が変わるので注意。

マイグレーション実行というのは、データベースにテーブルを作ること、つまりrails db:migrateを実行することです。

## マイグレーション実行前
アプリケーションフォルダ内で以下のコマンドを実行します。

```
$ rails destroy model [削除したいモデル名]
```

## マイグレーション実行後
**説明のため、まずはマイグレーションしてみます。**以下コマンドを実行。

説明の都合上、2つのモデルを作ってマイグレーションします。（なんの情報も持っていないモデルだけど気にしない。本当はカラム名:データ型, ...を後ろにつけます）

```
$ rails db:create # データベース作成(まだデータベースを作っていない場合)

$ rails g model user # userモデル作成
$ rails g model post # postモデル作成

$ rails db:migrate # テーブル作成
```

**ここからuserモデルとpostモデルを削除していきます。**

モデルを削除する際には、データベースにテーブルが作成されてしまっているのでそちらを削除してからモデルを削除する必要があります。

まずは以下コマンドを実行してみましょう。

```
$ rails db:migrate:status
```

マイグレーションを実行した一覧が出てきます。

```
 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200318134652  Create users
   up     20200318134702  Create posts
```

Statusがupになっているということはこのマイグレーションが実行されている（テーブルが作られている）ということ。

Migration Nameを見るとどんなマイグレーションか分かります。

以下コマンドのどれかを実行して、削除したいモデルのマイグレーションを取り消しましょう。

``` 
$ rails db:rollback # 1つだけ前の状態に戻す
$ rails db:rollback STEP=2 # 2つ前の状態に戻す
$ rails db rollback VERSION=20200318134652 # Migration ID：20200318134652のマイグレーションが実行された状態まで戻す
```

直前のマイグレーションが2つくらいならrails db:rollbackを2回やればいいですが、たくさん戻したいならステップ数やバージョンを指定すると楽です。（**不整合が起きるため、過去の特定のマイグレーションだけを取り消すことはできません。**）

これで実行したマイグレーションが取り消されたので、あとはマイグレーション実行前と同様に`rails destroy [モデル名]`で削除しましょう。

## マイグレーション取り消しの前にモデルを削除してしまった場合
せっかちで先に`rails destroy [モデル名]`を実行してしまった人のため。

例えば先の例でpostモデルを削除してしまったとします。するとpostのマイグレーションファイルも削除されてしまいrails db:rollbackでマイグレーションを取り消すことすらできなくなります。（絶望）

その場合は、まず以下コマンドで新しくマイグレーションファイルを作成します。

```
$ rails g migration [マイグレーション名]
```

マイグレーション名はなんでもいいですが、わかりやすくdrop_postとでもしておきましょう。

するとdb/migrate/内に以下ファイルが作成されます。

```
class DropPost < ActiveRecord::Migration[6.0]
  def change
  end
end
```

changeメソッド内に以下の様に追記しましょう。

```
class DropPost < ActiveRecord::Migration[6.0]
  def change
    drop_table :post # ここを追加
  end
end
```

そしてマイグレーションを実行します。するとpostテーブルが削除されているため一件落着。

```
$ rails db:migrate
```

無駄なマイグレーションファイルが残ってしまうのが個人的には嫌です。ファイルを削除しても基本問題ありませんがrails db:migrate:statusで表示される履歴の中にはしっかり残っています。（※原則としてマイグレーションファイルは削除しちゃだめです。）

```
 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200318145751  Create users
   up     20200318150431  ********** NO FILE **********
   up     20200318150544  ********** NO FILE **********
```

# scaffoldで作成したモデルやコントローラ等の削除
rails g scaffold [モデル名] カラム名:データ型 (カラム名:データ型...)でモデルやコントローラやルーティングなどを一括作成してくれます。詳しくは他の記事を参照してください。

rails g scaffoldで作成したんだからもちろん削除は以下コマンド。全部スッキリ削除してくれます。

```
rails destroy scaffold [モデル名]
```

# データベース内のデータを削除
モデルやコントローラ、ビューなどを作成し、色々試していているとデータベース内のデータがごちゃってきて初期状態に戻したい時があると思います。そういうときは以下コマンドを実施。

rails db:reset
今あるデータベースを削除して新しくもう一度作ってくれます。

**db/seeds.rbを使って初期データ投入を行っている場合は初期データ投入も同時にやってくれる**ので、自分でrails db:seedを行うと二重にデータが入ってしまいます。

# さいごに
以上、Ruby on Rails 削除関連まとめでした。

他にも削除系の操作があれば教えてください。追記します。

[Twitter@ruemura3](https://twitter.com/ruemura3/)