Laravel基本の流れ③ Model・migrationを理解して、データベースを扱おう

Laravelでは、
データベースのテーブルを扱うために「Model」を、
データベースにテーブルを作成・変更を行うために「migrationファイル」を使用します。
今回はこの２つについて学びましょう。

### Step.1 「Model」「migrationファイル」を作成する
　前回の「Breeze」のおかげで、ユーザー管理用のテーブル`users`は作成されています。今回はtwitterのような、投稿するテキスト・画像を管理する`tweets`テーブルを作成していきます。

まずprojectに移動しましょう。
```
cd Laravelproject
```
「Model」だけを作成したい場合は、下のコマンドを実行します。
```
php artisan make:model Tweet
```
※ 「Tweet」はModelの名前なので、適宜考えて付けましょう。

このとき、最後に 「-m」 をつけると、同時にmigrationファイルも作成されます。
どうせmigrationファイルも必要となるので、こちらの方がいいでしょうね。

```
php artisan make:model Tweet -m
```
　これで、

・`Model`　app -> Models -> Tweet.php　
・`migrationファイル`　database -> migrations -> 今日の日付の名前のファイル

の２つが作成されました。

:::note alert
migrationsの中には、古い日付の名前のファイルが複数ありますが、これには触れません。
:::

### Step.2　migrationファイルを用いてテーブルを作成する



・`Model`：データベースにどんなデータを書き込むのかなどを決める
・`migrationファイル`：データベースにテーブルを作ったり、変更したりするためのファイル

ということで、migrationファイルを利用して、テーブルを作成していきます。

:::note warn
きちんとmigrationファイルからデータベースを扱っていると、deproyのときスムーズにlocalと同じデータベースを構築することができます。極力phpmyadminなどで直接データベースをいじるのは避けましょう。deproyの時に詰みます。
:::

　データベースに必要なカラムを持つテーブルを作成します。
`database -> migrations`内に作成された、日付から始まるmigrationファイルを開きましょう。

`up`の中に、必要なカラムを記述します。

```php:〇〇_create_tweets_table.php
public function up()
  {
    Schema::create('tweets', function (Blueprint $table) {
      $table->id();
      // 🔽 ここから追加
      $table->string('tweet');
      $table->text('description')->nullable();
      // 🔼 ここまで追加
      $table->timestamps();
    });
  }
```
・string型（短めの文字列）の「tweet」というカラム
・text型（長めの文字列）の「description」というカラム

の２つのカラムを追加しました。
なお、id、timestampsはデフォルトで設定されています。
・timestamps()は、「created_at」「updated_at」の２つのカラムを作成してくれます。
・nullableはカラムに「null」を入れることができる。

準備が終わったらmigrationを実行し、テーブルを作成します。

```
php artisan migrate
```
データベースを確認すると「tweets」というテーブルができています。

:::note info
Modelの名前を「Tweet」として作成すると、テーブル名は「tweets」となるように、先頭の文字が小文字の複数形の名前のテーブルができます。
:::

:::note warn
migrationをやり直したいときは

```
php artisan migrate:rollback
```

と叩けば、元に戻すことが可能です。
:::

データ型は色々あるので、最初は調べながら書くことになるでしょうね。下に２つ参考に書いておきます。

```
   $table->integer('send_to')->nullable();　　　　　　//integer型（整数）
   $table->boolean('user_type'); 　　　　　　　　　　　　　　　　　　　　　　　//boolean型（true or false）
```


:::

### Step.3 Modelでテーブルを管理する（fillableまたはguarded)

　テーブルのどのカラムにはデータを入れて、どれには入れないかをModelに記載して決めておきます。
`fillable`を使うと

`app -> Models -> Tweet.php`

```php:Tweet.php
class Tweet extends Model
{
    use HasFactory;
    protected $fillable = [
        'tweet',
        'description',
    ];
}
```

これで「tweet」「description」カラムにはデータを入れることが可能ということになります。
逆に`guarded`を使うと指定のカラムはいじってはダメ！という指定をすることもできます。



### Step.4 リレーション（※必要であれば）
　リレーションを行うことで、複数のテーブルを関連付けて扱うことができます。必須ではありませんが、多くの場合必要になると思います。例として、usersテーブルとtweetsテーブルを`user_id（Model名小文字_idとする必要があります。)`で紐づけてみます。
　まず「tweetsテーブル」に、`user_idカラム`を作っておきましょう。カラムの追加など、テーブルを操作するのは「migrationファイル」でしたね。

①関連づけるためのカラム（ここでは「user_id」）を追加する。
　→ migrationファイルを作成します。

```
php artisan make:migration add_column_user_id_to_tweets_table --table=tweets
```
database -> migrationsにできた一番新しいmigrationファイルの中に、次のように追加

```php:一番新しいmigrationファイル

public function up()
{
    Schema::table('tweets', function(Blueprint $table){
        $table->foreignId('user_id')->after('id')->nullable();
    });
}

```
「idカラムの後にuser_idカラムを追加してね」
さらにdown()メソッドも書いておくと、rollbackで取り消すことができます。
```php:一番新しいmigrationファイル
public function down()
{
    Schema::table('tweets', function(Blueprint $table){
        $table->dropColumn('user_id');
    });
}

```
できたらターミナルでmigrate

```
php artisan migrate
```

これでidカラムの下にuser_idカラムができているはずです。これを利用して次の２つのリレーションを設定してみましょう。


（1対多のリレーション）
　今回に例では、ユーザーを管理する`usersテーブル`と、投稿されたtweetを管理する`tweetsテーブル`が分かれています。実際には1人のユーザーが複数のtweetを投稿するので、ユーザーの`id`をtweetの`user_id`へ入れておくことができれば、一発でそのユーザーが投稿したtweeetがどれなのか分かりますよね。
　このように1人のユーザーに複数のデータを紐づけることを「1対多のリレーション」と言います。親となる`users　Model`に次のように追加します。

`app -> Modesls -> Users.php`

```php:Users.php
class User extends Authenticatable
{
    use HasApiTokens,HasFactory,Notifiable;

    public function tweets()
  {
    return $this -> hasMany(Tweet::class);
  }
}
```

１人のUserには複数のTweetが紐づくので`hasMany`を使い、`tweets`と複数形にします。

（多対1のリレーション）
　1対多とは逆に、tweetから見ると、複数のtweetが同じ1人のユーザーによって投稿されているです。このように複数のデータに対して、1人のユーザーを紐づけることを「多対1のリレーション」と言い、今度は`tweet Model`に、次のように記載しましょう。

`app -> Modesls -> Tweet.php`

```php:Tweet.php
class Tweet extends Model
{
    use HasFactory;

    public function user()
  {
    return $this -> belongsTo(User::class);
  }
}
```

とします。１つのTweetには1人のユーザーが紐づくので`belongsTo`を使い、`users()`ではなく`user()`とします。

おそらくこの２つとも使うことが多いと思いますので、どちらも設定しておいた方が良いかもしれません。
使い方は実際のプロダクトを作りながら見てもらいたいと思います。

次の記事

https://qiita.com/taisuke-m/items/e188abe6c63f0f9bb051