【Laravel】ソフトデリート/主キー・外部キーを複数生成

# 環境
・Laravel10
・XAMPP
・Windoows11
# やること
１：Userテーブル作成
・ `deleted_at`はソフトデリート
|カラム名前|タイプ|属性|デフォルト値|その他|
|--|--|--|--|--|
|user_id|bigint|UNSIGNED|なし|AUTO_INCREMENT|
|email|varchar||なし|
|created_at|timestamp||NULL|
|updated_at|timestamp||NULL|
|deleted_at|timestamp||NULL|

２：Likesテーブル作成
・`from_user_id` `to_user_id`に主キーと外部キーを設定。
・Usersテーブルの `user_id` を参照
※外部キーを設定する際、参照先とタイプを合わせないとエラーがでる。
|カラム名前|タイプ|属性|デフォルト値|その他|
|--|--|--|--|--|
|from_user_id|bigint|UNSIGNED|なし||
|to_user_id|bigint|UNSIGNED|なし|
|created_at|timestamp||NULL|
|updated_at|timestamp||NULL|

# １.Userテーブル作成
```php:create_users_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id('user_id');
            $table->string('email');
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
            $table->softDeletes();

        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('users');
    }
};

```
・`$table->softDeletes();`は、`deleted_at`カラムを自動生成
```php:User.php
<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use Illuminate\Database\Eloquent\SoftDeletes;


class User extends Authenticatable implements JWTSubject
{
    use HasApiTokens, HasFactory, Notifiable, SoftDeletes;

    protected $primaryKey = 'user_id';

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'user_id',
        'email',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
        'password' => 'hashed',
    ];

}

```
〇ソフトデリート
・`use Illuminate\Database\Eloquent\SoftDeletes;`
・`use SoftDeletes`

〇主キー
・`protected $primaryKey = 'user_id';`
id以外の名前を主キーに設定したい場合は必要
# ２.Likesテーブル作成
```php:create_likes_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('likes', function (Blueprint $table) {
            $table->unsignedBigInteger('from_user_id');
            $table->unsignedBigInteger('to_user_id');
            $table->timestamps();

            $table->foreign('from_user_id')->references('user_id')->on('users')->onDelete('cascade');
            $table->foreign('to_user_id')->references('user_id')->on('users')->onDelete('cascade');
            
            $table->primary(['from_user_id', 'to_user_id']);
            $table->unique(['from_user_id', 'to_user_id']);
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('likes');
    }
};
```
〇主キー
・`user_id`のタイプを合わせるため`unsignedBigInteger`
・`$table->primary(['from_user_id', 'to_user_id']);`で主キーにするカラム設定
・`$table->unique(['from_user_id', 'to_user_id']);`で一意制約設定。

※一意制約：テーブル内のデータが重複しないことを保証。
※unique()は、指定されたカラム・カラムの組み合わせが一意であることをデータベースに伝える。

→同じユーザーが同じ投稿に複数回のLikeを付けることを防ぐ。from_user_idとto_user_idの組み合わせが既に存在する場合、新しい行が挿入されることを防ぐ。
```php:Like.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Like extends Model
{
    use HasFactory;
    
    public $incrementing = false;

    protected $fillable = [
        'from_user_id',
        'to_user_id',
    ];
}
```

# 結果

〇Likesテーブル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/597f7845-6fcb-87ef-4244-7a0fca6d166c.png)