ひとつのテーブルに対して、複数のデータでリレーションする【CakePHP4】

概要

ユーザテーブルと記事テーブルはすでにリレーションしてるけど、編集者やチェック担当者など、他のリレーションを設けるにはどうするか?というお話です。

前提

下記のようなUsers(ユーザ)テーブルと、Articles(記事)テーブルがあるとします。

Users
・id(int)
・name(varchar)

Articles
・id(int)
・user_id(int)
・text(varchar)

UserとArticleはリレーションしています。

src/Model/UsersTable.php

class UsersTable extends Table
{
    public function initialize(array $config): void
    {
        //...省略

        $this->hasMany('Articles', [
            'foreignKey' => 'user_id',
        ]);

src/Model/ArticlesTable.php

class ArticlesTable extends Table
{
    public function initialize(array $config): void
    {
        //...省略

        $this->belongsTo('Users', [
            'foreignKey' => 'user_id',
            'joinType' => 'INNER',
        ]);

やりたいこと

UserとArticleのリレーションはすでに存在しますが、新たなカラムでのリレーションを追加するとします。

具体的にはArticlesを以下のようにします。

Articles
・id(int)
・user_id(int)・・・作成者(既存)
・editor_id(int)・・・編集者(新規追加)
・text(varchar)

もともとuser_idでusersテーブルとリレーションしていましたが、ここにeditor_idを追加しこのデータでもusersとリレーションさせます。

既存のuser_idによるリレーションは作成者としてそのまま利用し、新たに「編集者」の概念を追加します。

コード

src/Model/UsersTable.php

class UsersTable extends Table
{
    public function initialize(array $config): void
    {
       //...省略
       //既存のリレーション。作成者として利用
       $this->hasMany('Articles', [
            'foreignKey' => 'user_id',
       ]);

       //新規リレーション。編集者として利用
       $this->hasMany('EditorArticles', [
            'className' => 'Articles',
            'foreignKey' => 'editor_id',
      ]);

src/Model/ArticlesTable.php

class ArticlesTable extends Table
{
    public function initialize(array $config): void
    {
       //...省略
       //既存のリレーション。
       $this->belongsTo('Users', [
            'foreignKey' => 'user_id',
            'joinType' => 'INNER',
        ]);

       //新規リレーション。
       $this->belongsTo('Editors', [
            'className' => 'Users',
            'foreignKey' => 'editor_id',
            'joinType' => 'LEFT',
        ]);

これで以下のように利用可能となります。

src/Controller/SamplesController.php

use Cake\ORM\TableRegistry;
//省略
class SamplesController extends AppController
{
      $usersTable = TableRegistry::getTableLocator()->get('Users');
      $articlesTable = TableRegistry::getTableLocator()->get('Articles');

      //作成記事と編集記事をそれぞれ取得できる。
      $users = usersTable->find()->contain('Articles','EditorArticles')->all();

      //作成者と編集者をそれぞれ取得できる。
      $articles = articlesTable->find()->contain('Users','Editors')->all();
}

参考

CakePHP4公式:アソシエーション

コメント

タイトルとURLをコピーしました