概要
ユーザテーブルと記事テーブルはすでにリレーションしてるけど、編集者やチェック担当者など、他のリレーションを設けるにはどうするか?というお話です。
前提
下記のような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公式:アソシエーション
コメント