LaravelのEloquent ORM：リレーションシップとクエリについて

## はじめに
こんにちは、Webエンジニアの岩田史門([@SI_Monxy](https://x.com/SI_Monxy))です！
今回はLaravelのEloquent ORMについて記事を書いてみました！
改善点や修正点があれば、コメントにて優しくご指導いただけると嬉しいです！

## 概要
LaravelのEloquent ORM（Object-Relational Mapping）は、データベースとのやり取りをシンプルかつ直感的に行うための強力なツールです。本記事では、Eloquent ORMを使用したデータベースリレーションシップの管理方法と、クエリの書き方について解説します。リレーションシップの定義方法、クエリの基本、そして実践的なサンプルコードを紹介します。

## Eloquentのリレーションシップの基本
Eloquent ORMでは、リレーションシップを簡単に定義し、使用することができます。リレーションシップを定義することで、関連するデータをシンプルに取得でき、クエリを効率的に行うことができます。

## リレーションシップの種類
## One-to-One
One-to-Oneリレーションシップは、1つのモデルが1つの関連モデルを持つ場合に使用します。例えば、ユーザーとそのプロファイルがこの関係に当たります。

``` php
// Userモデル
public function profile()
{
    return $this->hasOne(Profile::class);
}

// Profileモデル
public function user()
{
    return $this->belongsTo(User::class);
}
```

## One-to-Many
One-to-Manyリレーションシップは、1つのモデルが複数の関連モデルを持つ場合に使用します。例えば、ブログポストとそのコメントがこの関係に当たります。

``` php
// Postモデル
public function comments()
{
    return $this->hasMany(Comment::class);
}

// Commentモデル
public function post()
{
    return $this->belongsTo(Post::class);
}
```

## Many-to-Many
Many-to-Manyリレーションシップは、複数のモデルが互いに複数の関連モデルを持つ場合に使用します。例えば、ユーザーとロール（役割）がこの関係に当たります。

``` php 
// Userモデル
public function roles()
{
    return $this->belongsToMany(Role::class);
}

// Roleモデル
public function users()
{
    return $this->belongsToMany(User::class);
}
```

## Has-Many-Through
Has-Many-Throughリレーションシップは、モデルが中間モデルを介して複数の関連モデルを持つ場合に使用します。例えば、国とその経由しているユーザーの投稿がこの関係に当たります。

``` php 
// Countryモデル
public function posts()
{
    return $this->hasManyThrough(Post::class, User::class);
}
```

## Polymorphic Relations
Polymorphicリレーションシップは、複数のモデルが共通の関係を持つ場合に使用します。例えば、画像がユーザーやポストなど様々なモデルに関連付けられる場合です。

``` php
// Imageモデル
public function imageable()
{
    return $this->morphTo();
}

// Userモデル
public function images()
{
    return $this->morphMany(Image::class, 'imageable');
}

// Postモデル
public function images()
{
    return $this->morphMany(Image::class, 'imageable');
}
``` 

## リレーションシップを使ったクエリ
Eloquentを使用することで、リレーションシップを簡単にクエリに含めることができます。例えば、ユーザーとその投稿を取得するには以下のようにします。

``` php
$users = User::with('posts')->get();
```

さらに、条件を追加してクエリを絞り込むことも可能です。

``` php 
$users = User::whereHas('posts', function($query) {
    $query->where('title', 'like', '%Laravel%');
})->get();
```

## サンプルコード
### モデルの定義
``` php 
// Userモデル
class User extends Model
{
    public function profile()
    {
        return $this->hasOne(Profile::class);
    }

    public function posts()
    {
        return $this->hasMany(Post::class);
    }

    public function roles()
    {
        return $this->belongsToMany(Role::class);
    }
}

// Profileモデル
class Profile extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

// Postモデル
class Post extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

// Roleモデル
class Role extends Model
{
    public function users()
    {
        return $this->belongsToMany(User::class);
    }
}
```

### リレーションシップを使ったクエリ
``` php 
// ユーザーとそのプロファイルを取得
$userWithProfile = User::with('profile')->find(1);

// 特定の条件を満たす投稿を持つユーザーを取得
$usersWithPosts = User::whereHas('posts', function($query) {
    $query->where('title', 'like', '%Laravel%');
})->get();
```

## まとめ
LaravelのEloquent ORMを使用することで、リレーションシップを簡単に定義し、クエリを効率的に実行できます。One-to-One、One-to-Many、Many-to-Many、Has-Many-Through、Polymorphic Relationsの各リレーションシップを理解し、適切に使用することで、データベースの設計と操作がよりシンプルになります。

## 参考
- [Laravel Documentation - Eloquent ORM](https://laravel.com/docs/11.x/eloquent)
- [Laravel Documentation - Relationships](https://laravel.com/docs/11.x/eloquent-relationships)