カテゴリー
Linux

Laravel 5.8 で多対多構造を belongsToMany の引数をほぼ使い尽くしてなんとしてでもリレーションを実現する方法

Laravel 5.8 における belongsToMany の引数まとめ

  • 第 1 引数では最終的な接続先モデル名を名前空間含めて指定する
  • 第 2 引数では中間テーブル名を指定する
  • 第 3 引数では接続元モデル ID を示す中間テーブル内のカラム名を指定する
  • 第 4 引数では最終的な接続先モデル ID を示す中間テーブル内のカラム名を指定する
  • 第 5 引数では接続元モデル ID のカラム名を指定する
  • 第 4 引数では最終的な接続先モデル ID のカラム名を指定する

具体例

多対多リレーションを定義するために用いる WordPress のテーブル

データベース関連図 データベース構造 – WordPress Codex 日本語版 から抜粋です。

Laravel 5.8 において belongsToMany の引数を 6 つ指定して多対多構造を定義するために用いたテーブル

  • 接続元: wp_term_taxonomy
    • 主キー名: term_taxonomy_id
  • 中間テーブル: wp_term_relationships
    • 接続元のキー名: term_taxonomy_id
    • 接続先のキー名: object_id
  • 接続先: wp_posts
    • 主キー名: ID

コード

接続元の TermTaxonomy モデルクラスに belongsToMany のメソッド posts を定義しました。

<?php

namespace App\Models\Wp;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class TermTaxonomy extends Model
{
    /**
     * この TermTaxonomy に所属する Post を取得します。
     *
     * @return
     */
    public function posts(): BelongsToMany
    {
        return $this->belongsToMany(
            'App\Models\Wp\Post',
            'wp_term_relationships',
            'term_taxonomy_id',
            'object_id',
            'term_taxonomy_id',
            'ID'
        );
    }
}

確認

# php artisan tinker
Psy Shell v0.9.9 (PHP 7.3.3 — cli) by Justin Hileman
>>> App\Models\Wp\TermTaxonomy::first()->posts
=> Illuminate\Database\Eloquent\Collection {#3056
     all: [
       App\Models\Wp\Post {#3055
         ID: 1,
         post_author: 1,
         post_date: "2019-06-02 10:24:29",
         post_date_gmt: "2019-06-02 01:24:29",
         post_content: """
           <!-- wp:paragraph -->\n
           <p>WordPress へようこそ。こちらは最初の投稿です。編集または削除し、コンテンツ作成を始めてください。</p>\n
           <!-- /wp:paragraph -->
           """,
         post_title: "Hello world!",
         post_excerpt: "",
         post_status: "publish",
         comment_status: "open",
         ping_status: "open",
         post_password: "",
         post_name: "hello-world",
         to_ping: "",
         pinged: "",
         post_modified: "2019-06-02 10:24:29",
         post_modified_gmt: "2019-06-02 01:24:29",
         post_content_filtered: "",
         post_parent: 0,
         guid: "http://localhost:8080/?p=1",
         menu_order: 0,
         post_type: "post",
         post_mime_type: "",
         comment_count: 1,
         pivot: Illuminate\Database\Eloquent\Relations\Pivot {#3052
           term_taxonomy_id: 1,
           object_id: 1,
         },
       },
     ],
   }
>>>

おわりに

多対多 Eloquent:リレーション 5.8 Laravel が公式ドキュメントです。

これを読むと、第 4 引数までの指定方法しかありません。接続元と接続先のプライマリーキー名が id 以外の場合は belongsToMany は使えないのでしょうか?

そんなことはありません。

上記の公式 API ドキュメント、そして GitHub の Laravel コードを確認すると、第 7 引数まで指定できます。

そして、第 5 、第 6 引数が、接続元と接続先のプライマリーキー名ということもわかりました。

インターネットを検索しますと Laravel 公式ドキュメントの範囲内のみの使い方を説明しているページは多くありましたけれども、それを超える解説は見当たりませんでしたので、今回ノートいたしました。

以上です。

「Laravel 5.8 で多対多構造を belongsToMany の引数をほぼ使い尽くしてなんとしてでもリレーションを実現する方法」への2件の返信

ひと癖あるリレーションを設定したくて、なかなか情報にたどり着かず困っていたところ、まさに求めていた内容でとても参考になりました。
APIドキュメントのほうに詳細が記載されているのですね。出典の表示も助かりました!ありがとうございます。

コメントを残す