Rails6 のちょい足しな新機能を試す95（db:prepare 編）

# はじめに

Rails 6 に追加された新機能を試す第95段。 今回は、 `db:prepare` 編です。
Rails 6 では、 `db:prepare` という rake タスクが追加されました。

データベースが存在しないときは、データベースを作成してから、 schema.rb からテーブルを作成（ロード）し `db:seed` を実行します ( `db:setup` と同じ動作 )。
データベースが存在するときは、 `db:migrate` を実行します。

Ruby 2.6.4, Rails 6.0.0 で確認しました。

```shell
$ rails --version
Rails 6.0.0
```

# 今回の下準備


今回は [Rails6 のちょい足しな新機能を試す93（ActiveRecord extract_associated編）]() を利用して確認します。


# 一旦 db:drop する。

動作確認のため、一旦 `db:drop` します。


```shell
$ bin/rails db:drop
```

# bin/rails db:prepare を実行する

```shell
$ bin/rails db:prepare
Created database 'app_development'
Created database 'app_test'
```

# データを確認する

`bin/rails console` でデータを確認します。

development 環境はデータができていることがわかります。

```irb
$ bin/rails c
Running via Spring preloader in process 649
Loading development environment (Rails 6.0.0)
irb(main):001:0> Book.all
  Book Load (0.2ms)  SELECT "books".* FROM "books" LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Book id: 1, title: "Pragmatic Programmer", author_id: 1, created_at: "2019-09-28 11:41:53", updated_at: "2019-09-28 11:41:53">, #<Book id: 2, title: "Programming Ruby", author_id: 1, created_at: "2019-09-28 11:41:53", updated_at: "2019-09-28 11:41:53">, #<Book id: 3, title: "Agile Web Development with Rails 6", author_id: 1, created_at: "2019-09-28 11:41:53", updated_at: "2019-09-28 11:41:53">, #<Book id: 4, title: "Agile Web Development with Rails 5.1", author_id: 1, created_at: "2019-09-28 11:41:53", updated_at: "2019-09-28 11:41:53">, #<Book id: 5, title: "The Ruby Programming Language", author_id: 2, created_at: "2019-09-28 11:41:53", updated_at: "2019-09-28 11:41:53">, #<Book id: 6, title: "Programming Python", author_id: 3, created_at: "2019-09-28 11:41:53", updated_at: "2019-09-28 11:41:53">]>
```

# db:create した状態で db:prepare を実行する

`db:drop db:create` してから `db:prepare` を実行します。

`db:drop db:create` を実行します。

```shell
$ bin/rails db:drop db:create
Dropped database 'app_development'
Dropped database 'app_test'
Created database 'app_development'
Created database 'app_test'
```

`db:prepare` を実行します。

```shell
$ bin/rails db:prepare
== 20190927002833 CreateAuthors: migrating ====================================
-- create_table(:authors)
   -> 0.0098s
== 20190927002833 CreateAuthors: migrated (0.0098s) ===========================

== 20190927002849 CreateBooks: migrating ======================================
-- create_table(:books)
   -> 0.0201s
== 20190927002849 CreateBooks: migrated (0.0202s) =============================
```

books テーブル, authors テーブルのデータを確認するとデータはできてません。 `db:seed` は実行されていません。

```irb
irb(main):001:0> Book.all
  Book Load (0.2ms)  SELECT "books".* FROM "books" LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation []>
irb(main):002:0> Author.all
  Author Load (0.3ms)  SELECT "authors".* FROM "authors" LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation []>
```

# db:setup との違い

`db:setup` は、 データベースが存在するときの動作が、 `db:prepare` とは異なります。
schema.rb からテーブルを作成し直して、seed データを投入します。
また、実行していないマイグレーションがあるとメッセージを表示します。
(`db:setup` 実行前の状態には戻りません。 `db:setup` 実行時の schema.rb によりテーブルの再作成は実行されます。)

```shell
$ bin/rails db:setup
Database 'app_development' already exists
Database 'app_test' already exists
You have 1 pending migration:
  20190927002849 CreateBooks
Run `rails db:migrate` to update your database then try again.
```

# 試したソース

試したソースは以下にあります。
https://github.com/suketa/rails_sandbox/tree/try093_extract_associated

# 参考情報

* [What is new in Rails 6.0](https://bogdanvlviv.com/posts/ruby/rails/what-is-new-in-rails-6_0.html)
* [Add db:prepare rake task](https://github.com/rails/rails/pull/35768)