Laravel クエリビルダでjoin句を使用する

# 目的

- クエリビルダを使ったテーブル結合の方法をまとめる

# 実施環境

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.5) |
| ハードウェア | MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) |
| プロセッサ | 2 GHz クアッドコアIntel Core i5 |
| メモリ | 32 GB 3733 MHz LPDDR4 |
| グラフィックス | Intel Iris Plus Graphics 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHP バージョン | 7.4.3 | Homwbrewを用いて導入 |
| Laravel バージョン | 7.0.8 | commposerを用いてこちらの方法で導入→[Mac Laravelの環境構築を行う](https://qiita.com/miriwo/items/adaaaeecae69d6392e08) |
| MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いてこちらの方法で導入→[Mac HomebrewでMySQLをインストールする](https://qiita.com/miriwo/items/ef6a064bc545fbea29d9) |

# 前提環境

- 下記の内容をすでに実施してること
    - [Laravel クエリビルダを駆使する](https://qiita.com/miriwo/items/c850a62c3e3496f62dd7)

# 前提情報

- statusesテーブルを新たに作成し、テーブル内に格納されているデータをクエリビルダのjoin句を用いてデータを取得して表示する。
- コードの解説は本記事の下部の「ミニ解説」にてちょっとだけ解説している。

# 読後感

- クエリビルダのjoin句の使用方法の基礎が分かる。

# 概要

1. statusesテーブルの作成
1. コントローラの修正(クエリビルダの追記)
1. ビューの修正
1. データの格納
1. 確認

# 詳細

1. statusesテーブルの作成
    1. アプリ名ディレクトリで下記コマンドを実行してモデルファイルとマイグレーションファイルを作成する。

        ```terminal
        $ php artisan make:model Status --migration
        ```
    1. アプリ名ディレクトリで下記コマンドを実行してマイグレーションファイルを開く。

        ```terminal
        $ vi database/migrations/YYYY_MM_DD_XXXXXX_create_statuses_table.php
        ```
    1. 開いたマイグレーションファイルを下記の様に追記修正する。

        ```アプリ名ディレクトリ/database/migrations/YYYY_MM_DD_XXXXXX_create_contents_table.php
        <?php
        
        use Illuminate\Database\Migrations\Migration;
        use Illuminate\Database\Schema\Blueprint;
        use Illuminate\Support\Facades\Schema;
        
        class CreateContentsTable extends Migration
        {
            /**
             * Run the migrations.
             *
             * @return void
             */
            public function up()
            {
                Schema::create('contents', function (Blueprint $table) {
                    $table->id();
                    //下記を追記
                    $table->string('status_name');
                    $table->timestamps();
                });
            }
        
            /**
             * Reverse the migrations.
             *
             * @return void
             */
            public function down()
            {
                Schema::dropIfExists('contents');
            }
        }
        ```
    1. アプリ名ディレクトリで下記コマンドをジックしてマイグレーションを実行する。

        ```terminal
        $ php artisan migrate
        ```
1. コントローラの修正(クエリビルダの追記)
    1. アプリ名ディレクトリで下記コマンドを実行してコントローラファイルを開く。

        ```terminal
        $ vi app/Http/Controllers/Controller.php
        ```
    1. 開いたコントローラファイルのoutputアクション内部を下記の様に修正する。

        ```アプリ名ディレクトリ/app/Http/Controllers/Controller.php
        <?php
        
        namespace App\Http\Controllers;
        
        use Illuminate\Http\Request;
        use App\Content;
        
        class ContentController extends Controller
        {
            public function output()
            {
                $contents_query = Content::select('*');
                //下記を追記
                $contents_query->join('statuses', 'contents.status_id', '=', 'statuses.id');
                $contents = $contents_query->get();
                return view('contents.output', [
                    'contents' => $contents,
                ]);
            }
        }
        ```
1. ビューの修正
    1. アプリ名ディレクトリで下記コマンドを実行してビューファイルを開く。

        ```terminal
        $ vi resources/views/contents/output.blade.php
        ```
    1. ビューファイルに下記を下記の様に修正する。

        ```アプリ名ディレクトリ/resources/views/contents/output.blade.php
        @foreach ($contents as $content)
            <hr>
            <p>{{$content['content']}}</p>
            <!-- 下記を修正 -->
            <p>{{$content['status_name']}}</p>
        @endforeach
        ```
1. データの格納
    1. アプリ名ディレクトリで下記コマンドを実行してtinkerを開く。

        ```terminal
        $ php artisan tinker
        ```
    1. tinkerにて下記を実行してstatusesテーブルにデータを追加する。

        ```php
        use App\Status;
        $b = new Status();
        $b->status_name = 'good'
        $b->save();

        $c = new Status();
        $c->status_name = 'bad'
        $c->save();
        ```
1. 確認

    1. 下記にアクセスし、ブラウザから当該アプリを確認する。
        - [http://127.0.0.1:8000/output](http://127.0.0.1:8000/output)

    1. 下記の様にブラウザで表示されることを確認する。

        <img width="480" alt="127_0_0_1_8000_output.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/7fb5babe-482a-078c-233d-1b32b6607f57.png">

# ミニ解説

### 「JOIN句の確認」のアクション内のコードについて

- 下記にコントローラのアクションのコードを記載する。

    ```アプリ名ディレクトリ/app/Http/Controllers/Controller.php
    public function output()
    {
        //DBにアクセスするためのクエリ文を組み立てている
        //Contentというモデルファイルに紐づいたテーブルの全てのカラムを取得する(SQL文のselect *と同じ)クエリ文を変数$contents_queryに格納している
        $contents_query = Content::select('*');
        //テーブルの結合を行う
        //クエリ文が格納されている変数->join('結合するテーブル名', '結合元テーブル名.結合するカラム名', '=', '結合先テーブル名.リンクするカラム名')
        $contents_query->join('statuses', 'contents.status_id', '=', 'statuses.id');
        //先に組み立てたクエリ文を実行して取得したデータを変数$contentsに格納している。
        $contents = $contents_query->get();
        return view('contents.output', [
            'contents' => $contents,
        ]);
    }
    ```