PHP

【Laravel】子、孫を含めた3つのテーブルからリレーションデータを取得する方法(Eloquentリレーション、ネスト)

Laravelを使って子、孫を含めた3つのテーブルからid(主キー)が一致するデータを取得し、一覧ページで表示する方法をご紹介します。

3つのテーブル構造

以下の3つのテーブルを用意しました。listpagesテーブルから商品を登録したユーザーが登録されてるusersテーブル(子)。usersテーブルに登録されてる都道府県id(todofuken_id)と一致するtodofukensテーブル(孫)の都道府県名(prefecture)を表示させます。

todofukensテーブル(孫)

名前説明
id主キー
prefecture都道府県名

usersテーブル(子)

名前説明
id主キー
nameユーザー名
emailメールアドレス
todofuken_id都道府県ID=todofukensテーブルのid
※todofukensテーブルのテーブル名から「s」を除いた名前「todofuken」とtodofukensテーブルの主キー「id」にアンダーバー「_」を付けた名前「todofuken_id」にする必要があります。こうすることでtodofukensテーブルからidが一致したデータを取得することができます。

listpagesテーブル

名前説明
id主キー
product_name商品名
user_id商品登録ユーザーID=usersテーブルのid
※usersテーブルのテーブル名から「s」を除いた名前「user」とusersテーブルの主キー「id」にアンダーバー「_」を付けた名前「user_id」にする必要があります。こうすることでusersテーブルからidが一致したデータを取得することができます。

子、孫を含めた3つのテーブルからリレーションデータを取得するためのModelの記述

※ListpageモデルにUserモデル、Todofukenモデルのデータを取得する記述をします。

class Listpage extends Model
{
	public function user()
	{
		//Userモデルのデータを取得する
	    return $this->belongsTo('App\User');
	}
	public function todofukens()
	{
		//Todofukenモデルのデータを取得する
	    return $this->belongsTo('App\Todofuken');
	}
}

子、孫を含めた3つのテーブルからリレーションデータを取得するためのControllerの記述

※listpagesテーブルのuser_idと一致するusersテーブルからidとnameを取得します。usersテーブルのtodofuken_idと一致するtodofukensテーブルからidとprefectureを取得します。
 with([‘user:id,name’,’user.todofuken:id,prefecture’])を使うことでusersテーブルから取得したいカラムのデータを指定し、usersテーブルにネストしたtodofukensテーブルの取得したいカラム(id,prefecture)を指定して取得します。

use App\User;   //Userモデルを使用
use App\Listpage;   //Listpageモデルを使用


    public function listdata(Request $request)
    {
        $sort = $request->sort;
        $order = $request->order;

	//listpagesテーブルのuser_idと一致するusersテーブルからidとnameを取得します。
	$listpages = Listpage::with(['user:id,name','user.todofuken:id,prefecture'])->orderBy('id', 'asc')->paginate(20);

        return view('listpages', [
            'listpages' => $listpages,
        ]);
    }

子、孫を含めた3つのテーブルからリレーションデータを取得するためのデータを表示させるview(一覧ページ)の記述

※listpagesテーブルの孫テーブルとなるtodofukensテーブルの都道県を表示させる場合は「{{ $listpage->user->todofuken->prefecture }}」を記述します。

                <table>
                    <thead>
                        <th>商品名</th>
                        <th>登録ユーザー</th>
                        <th>都道府県</th>
                    </thead>
                    <tbody>
                        @foreach ($listpages as $listpage)
                            <tr>
                                <!-- 商品名 -->
                                <td class="table-text">
                                    <div>{{ $listpage->product_name }}</div>
                                </td>
                                <!-- 登録ユーザー -->
                                <td class="table-text">
                                    <div>{{ $listpage->user->name }}</div>
                                </td>
                                <!-- 都道府県 -->
                                <td class="table-text">
                                    <div>{{ $listpage->user->todofuken->prefecture }}</div>
                                </td>
                            </tr>
                        @endforeach
                    </tbody>
                </table>

Routeの記述

※ページURLは必要に応じて変更して下さい。

Route::get('/listpages', 'ListpagesController@listdata');

 
 
※流用される場合は自己責任でお願いします。