Laravelでモデルの定義をしてみた


:::note info
前提
+ Laravel Version11
+ Docker for Windows Desktop
+ Laravel Sail使用
+ 過去記事「[Laravelをインストールしてみた](https://qiita.com/AKFJ21/items/c8f1052b7b321917cafc)」の状態
:::

## 概要
メッセージなどを投稿できる掲示板を作るため、そのモデルを設定します。

## 参照
+ https://laravel.com/docs/11.x/eloquent
+ https://laravel.com/docs/11.x/eloquent-relationships
+ https://laravel.com/docs/11.x/eloquent-mutators

## テーブル名：掲示板（boards）：表示項目
+ 投稿者ID(user_id):usersテーブルのid値を設定
+ タイトル(title)
+ カテゴリ(category)
+ 本文(texts)
+ 掲載期限(date_expiry)

## 作業
+ 1.モデルクラスの生成
+ 2.モデル定義
+ 2.1 $fillable配列の設定
+ 2.2 casts()ファンクションの設定
+ 2.3 他テーブルとの関係設定


## 1.モデルクラスの生成
Laravelのコマンドを使ってモデルクラスを定義するファイルを生成します。

```shell:コマンド
./vendor/bin/sail php artisan make:model Board
```

「Board」は生成したいクラス名です。単数形で先頭を大文字にするのがLaravel流のようです。


## 2.モデルクラス定義

```shell:app/Models/Board.php（生成された状態：抜粋）
  class Board extends Model
  {
      //
  }
```

### 2.1 $fillable配列の設定
これは安全（複数代入の脆弱性対策）のためのようです。例えば入力フォームの全項目を項目名１つ１つを定義せずにまとめてレコードに登録させるような場合、入力フォームをユーザーがいじって、記載している項目以外の項目に値が入ってしまうのを防ぐためのようです。
ですが、デフォルト値が設定されていない項目名を定義するようです。user_idはユーザーに入力してもらっては困る項目なので設定しなかったのですが、エラーが出てレコード保存されませんでした。
個人的には、ユーザーが入力可能な項目のみを設定する配列が他にあると良いのではと思いました。現状の配列だと、単にデフォルト設定されていない項目を自動的に取得すれば済むような気がします。

```shell:$fillableの設定
    protected $fillable = [
        'user_id',
        'title',
        'category',
        'texts',
        'date_expiry',
    ];
```

### 2.2 casts()ファンクションの設定
これは特定の項目の表示書式を固定的に設定しておくためのようです。
今回、掲載期限(date_expiry)項目が日付形式なので設定してみました。

```shell:casts()の設定
    protected function casts(): array
    {
        return [
            'date_expiry' => 'date:Y/m/d',
        ];
    }
```

### 2.3 他テーブルとの関係設定
usersテーブルとboardsテーブルは以下の関係で繋がっています。
users(テーブル)のid(項目)値 と boards(テーブル)のuser_id(項目)値が同じレコード

これはusersテーブルのレコード１つ(一人)に対してboardsテーブルのレコードが複数（投稿）ある関係です。
1対多の関係です。

この関係性を定義します。

```shell:app/Models/User.php
use Illuminate\Database\Eloquent\Relations\HasMany;
    public function boards(): HasMany
    {
        return $this->hasMany(Board::class);
    }
```
この設定をすることで特定ユーザーの掲示板を抽出できます。(例：$user->boards)

```shell:app/Models/Board.php
use Illuminate\Database\Eloquent\Relations\BelongsTo;
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }
```
この設定をすることで、特定掲示板の作成者を抽出できます。(例：$board->user)

```shell:app/Models/Board.php（編集後：抜粋）
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Board extends Model
{
    protected $fillable = [
        'user_id',
        'title',
        'category',
        'texts',
        'date_expiry',
    ];

    protected function casts(): array
    {
        return [
            'date_expiry' => 'date:Y/m/d',
        ];
    }

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

```shell:app/Models/User.php（編集後：抜粋）
use Filament\Models\Contracts\FilamentUser;
use Filament\Panel;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable implements FilamentUser
{

    use HasFactory, Notifiable;

    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    protected $hidden = [
        'password',
        'remember_token',
    ];

    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }

    public function boards(): HasMany
    {
        return $this->hasMany(Board::class);
    }

    ・・・
    
}
```