【Rails】モデル・マイグレーション・スキーマの違い

`モデル`と`マイグレーションファイル`と`schemaファイル`がごちゃごちゃになってしまうので、違いをまとめます。

## 1. モデル
#### 役割：
データベースのテーブルと対応するRubyクラス。  
**アプリケーションのロジックやデータの管理（バリデーションや関連性の設定）を記述する。**
バリデーション（入力必須、文字制限など）やアソシエーション（他テーブルとの関連）を定義する。

#### ファイル名：
`app/models/モデル名.rb` 下記の場合は、book.rb

#### コード例：
```ruby
# app/models/book.rb
class Book < ApplicationRecord
  # バリデーション
  validates :title, presence: true, length: { maximum: 10 }
  validates :author, presence: true
  validates :price, presence: true
end
```

## 2. マイグレーションファイル
#### 役割：
**データベース構造の変更するための指示書。**
（テーブルの作成、削除、カラムの追加や削除など）
マイグレーションを利用することで、データベースの変更を簡単に管理・適用できる。
バージョン管理もでき、変更を安全に適用したり、元に戻したりすることが可能。

#### ファイル名：
Railsでは、`db/migrate/` ディレクトリ内に `YYYYMMDDHHMMSS_create_books.rb` のようなファイル名で生成され、タイムスタンプで区別される。
下記の場合は、`202311150001_create_books.rb`

#### コード例：
```ruby
# db/migrate/202311150001_create_books.rb
class CreateBooks < ActiveRecord::Migration[6.0]
  def change
    create_table :books do |t|
      t.string :title, limit: 10
      t.string :author
      t.integer :price
      t.timestamps
    end
  end
end
```

---

## 3. schemaファイル
#### 役割：
マイグレーションの履歴を基に生成されるデータベースのスナップショット。
**現在のデータベース構造を表している。**（文字制限はあるか、入力必須か、文字列？数字？など）
直接編集はせず、`rails db:migrate` を実行すると自動で更新される。
あくまで、**現在のデータベース構造を確認するためのもの。**
スキーマを修正することはあまりなのでは？と思っている。

#### ファイル名：
`db/schema.rb` 

#### コード例：
`created_at` と `updated_at` は、Railsで自動的に管理されるタイムスタンプのカラム。
`precision: 6` は、日時（`created_at` や `updated_at`）の精度を指定するオプション。
`null: false` は、そのカラムに `NULL` 値が入らないように制約を加えている。
```ruby
# db/schema.rb
ActiveRecord::Schema.define(version: 202311150001) do

  create_table "books", force: :cascade do |t|
    t.string "title", limit: 10
    t.string "author"
    t.integer "price"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end
end
```
---

## 作成手順
下記の順で作成していく。
1. **モデルとマイグレーションファイルを作成する**
1. **マイグレーションを実行して、データベースを更新する**
3. **モデルにバリデーションを追加する（必要に応じて）**

モデル⇒マイグレーション⇒スキーマの順で、設定していく。

### 1. **モデルとマイグレーションファイルを作成する**
Rails のジェネレータコマンドを使って、モデルとマイグレーションファイルを作成する。
```bash
rails generate model Book title:string author:string price:integer
```

これで以下の2つのファイルが生成される：
- `app/models/book.rb`（モデルファイル）
- `db/migrate/202311150001_create_books.rb`（マイグレーションファイル）

マイグレーションファイルを開いて確認し、適宜修正。

### 2. **マイグレーションを実行して、データベースを更新する**
マイグレーションを実行して、データベースに`books` テーブルを作成・更新し、スキーマを更新。
```bash
rails db:migrate
```
このコマンドにより、以下が行われる：
- `books` テーブルがデータベースに作成される。
- `db/schema.rb` が自動生成・更新される。

スキーマファイルを開き、適宜修正。

### 3. **モデルにバリデーションを追加する（必要に応じて）**
`app/models/book.rb` にバリデーションやビジネスロジックを追加する。
バリデーションを追加しても、`rails db:migrate`を再度する必要はない。

**`rails db:migrate`は、**
- 新しいテーブルを作成
- 既存のテーブルにカラムを追加、変更、削除
- 外部キー制約を追加
- インデックスを追加

した時に、再度実行する必要がある。

---

### モデル・マイグレーションの役割の違い
マイグレーションがあれば、モデルいらいないのでは？と思ってしまうが、それぞれ異なる目的で使われており、どちらも必要。
マイグレーションとモデルが一緒に動作することで、Railsアプリケーションは効率的にデータを扱うことができる。

**【モデル】**
**モデルは、アプリケーションのロジックやデータを管理するためのもの**。。
マイグレーションだけでは、アプリケーションのロジックやデータ操作のルールを管理することができない。

マイグレーションだけでは、`title` の長さ制限や `author` と `price` のバリデーションを定義できない。

---
  
**【マイグレーション】**
**データベース構造を変更するのはマイグレーション**。
マイグレーションは、テーブルやカラムの追加、変更、削除、インデックスや外部キー制約の追加など、データベースの構造そのものを変更するための仕組み。

例えば、`create_table` で新しいテーブルを作成したり、`add_column` で既存のテーブルにカラムを追加したり、`add_foreign_key` で外部キー制約を追加するのは**マイグレーション**で行う。

また、**`Book` モデル**だけがあっても、**マイグレーション**を使ってデータベースにテーブルを作成しない限り、データを格納する場所がない。