0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Laravel】Withメソッドの使い方(リレーション)

Last updated at Posted at 2024-10-02

はじめに

以下記事はリレーション関係を構築したテーブルからデータを効率的に取得できるWithメソッドを使う手順のメモになります

親テーブルと子テーブルの見分け方

親テーブルと子テーブルを見分けるためのポイントは以下の通りです。

外部キーの有無

子テーブルは必ず外部キーを持ちます。
これは親テーブルのプライマリーキーを参照するカラムです。

リレーションシップの方向

親テーブルは他のテーブルに参照されるため、リレーションシップの出発点となります。
子テーブルは親テーブルを参照し、その情報を持っています

1対1の場合

1対1のリレーションでは、一つのモデルが一つの関連モデルを持つ関係を表します。以下は、Userモデルが一つのProfileモデルを持つ場合です。

Model.php
// User.php
class User extends Model
{
    public function profile()
    {
        return $this->hasOne(Profile::class);
    }
}

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

データの取得

***controller.php
$user = User::with('profile')->find($id);

指定したユーザーIDのユーザーとそのユーザーのプロフィールが取得できます

1対多の場合

1対多のリレーションでは、一つの親モデルが複数の子モデルを持つ関係を表します。以下は、Userモデルが複数のPostモデルを持つ場合です。

Model.php

// User.php
class User extends Model
{
    public function posts()
    {
        return $this->hasMany(Post::class);
    }
}

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

データの取得

Userと関連するPostを同時に取得するには、以下のようにwithメソッドを使用します

***controller.php
$user = User::with('posts')->find($id);

これにより、指定したユーザーIDのユーザーとそのユーザーの全ての投稿が取得できます。

多対多

多対多のリレーションでは、複数のモデルが他の複数のモデルと関連している関係を表します。以下はPostモデルが複数のTagモデルを持ち、Tagモデルも複数のPostモデルを持つ場合です。

Model.php
// Post.php
class Post extends Model
{
    public function tags()
    {
        return $this->belongsToMany(Tag::class);
    }
}

// Tag.php
class Tag extends Model
{
    public function posts()
    {
        return $this->belongsToMany(Post::class);
    }
}

データの取得

***controller.php
$post = Post::with('tags')->find($id);

指定した投稿IDの投稿とその投稿に関連する全てのタグが取得できます

複数のリレーションが存在する場合

以下の例のように1つのモデルに対して複数のリレーションが設定されている場合、Withメソッドでデータを取得するには以下のようにコードを記述します

  • Userモデル

    • 1対多のリレーションでPostモデルを持つ
    • 1対1のリレーションでProfileモデルを持つ
  • Postモデル

    • 多対多のリレーションでTagモデルを持つ
Model.php
// User.php
class User extends Model
{
    public function posts()
    {
        //(1人のユーザーが複数の投稿を持つ)
        return $this->hasMany(Post::class);
    }

    public function profile()
    {
        
        return $this->hasOne(Profile::class);
    }
}

// Profile.php
class Profile extends Model
{
    public function user()
    {
        //(1人のユーザーに1つのプロフィールがある)
        return $this->belongsTo(User::class);
    }
}

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

    public function tags()
    {
        //(1つの投稿が複数のタグを持ち、1つのタグが複数の投稿に関連する)
        return $this->belongsToMany(Tag::class);
    }
}

// Tag.php
class Tag extends Model
{
    public function posts()
    {
        return $this->belongsToMany(Post::class);
    }
}

Withメソッドの使い方

複数のリレーションを一度に取得するためには、withメソッドにリレーション名をカンマで区切って指定します。
※ リレーション名とはモデルに記載したメソッド名を指します

***controller.php
$user = User::with(['posts.tags', 'profile'])->find($id);

Withメソッドの補足

User::with()

ユーザーモデルを基にリレーションを取得します。

['posts.tags', 'profile']

postsリレーションの中にあるtagsリレーションと、profileリレーションを指定しています。

find($id)

特定のユーザーIDを指定して、そのユーザーと関連するデータを取得します。

取得できるデータ
  • ユーザー情報
  • そのユーザーが持つ全ての投稿情報
  • 各投稿が持つ全てのタグ情報
  • そのユーザーのプロフィール情報

まとめ

ithメソッドを使うことで、複数のリレーションを一度に効率的に取得することができ、パフォーマンスが向上します

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?