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?

More than 3 years have passed since last update.

Laravel 8 の Model を使って複数のキーでリレーションをする方法

Posted at

こんにちは、最近またLaravelをゴリゴリ書いています。

以前Laravelを使ってからもう1.5年ほど経って、色々とお作法が変わっていたり忘れていたりしたので結構戸惑いました。

とくに、データベースのリレーションには苦労しましたです、はい…

ということで、タイトルの通り「複数のカラムの値を使って、別のテーブルのデータを絞り込んだ上で取り込みたい!」という願いを叶える方法を書き残しておきます。

上級サブクエリというなんかすごそうな名前の機能を使う

Laravelのドキュメントでいうと、下記のページにやり方が記載されています。

この中の上級サブクエリを使って求める結果を得るのです。

まず、下記のようなテーブルを用意します。

companies

id name
1 有限会社倉敷
2 株式会社足軽
3 株式会社

branch_offices

id name company_id
1 東京本社 1
2 愛知本社 2
3 神奈川本社 3
4 長野支社 1
5 沖縄支社 1
6 東京支社 2
7 北海道支社 3

emproyees

id name company_id branch_office_id
1 徳川 1 1
2 織田 1 4
3 上杉 1 5
4 2 2
5 坂本 2 6
6 西郷 3 7

これらをもとに、社名と勤務先を含んだ従業員 (emproyee) 一覧を作りたいとします。

そうなるとですよ、会社名はいいとして、勤め先の本社や支社は company_id, branch_office_id を使って絞り込む必要があるわけです。

最終的には下記のようなデータが欲しいわけですよ。

ID 名前 会社名 支店名
1 徳川 有限会社幕末 東京本社
2 西郷 有限会社幕末 長野支社
3 中岡 有限会社幕末 沖縄支社
4 上杉 株式会社戦国 愛知本社
5 織田 株式会社戦国 東京支社
6 スサノオ 株式会社ヤマト 北海道支社

Modeでサブクエリを書く

これを実現するために書くコードは下記の通り。

Emproyee.php
<?php

namespace App\Models;

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

class Customer extends Model
{
    use HasFactory;

    public function company()
    {
        return $this->belongsTo(Company::class);
    }
}
HomeController
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Employee;
use App\Models\BranchOffice;

class HomeController extends Controller
{
    public function home(Request $request)
    {
        $query = Employee::addSelect(['branch_office' => BranchOffice::select('name')
            ->whereColumn('company_id', 'branch_offices.company_id')
            ->whereColumn('branch_office_id', 'branch_offices.id')]);
        $employees = $query->get();

        foreach ($employees as $employee) {
            static $employeesArray;
            $employeesArray[] = [
                'id' => $employee->id,
                'name' => $employee->name,
                'company' => $employee->company->name,
                'branch_office' => $employee->branch_office,
            ];
        };

        return view('welcome', ['employees' => $employeesArray]);
    }
}

ということで、addSelectのサブクエリでwhereColumnを2つ繋げばいいというだけでした。

わかってみれば非常に簡単に組み立てられますね。

この手の道具は普段から触っておかないとだめだな…

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?