0
0

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 1 year has passed since last update.

CakaPHP4でユーザ追加時に関連するテーブルも同時に追加を行う方法

Last updated at Posted at 2022-05-14

はじめに

実務でCakePHPを使って社内業務用のWEBアプリケーションを開発しました。
その際、細かい仕様の部分を悩みながら開発を進めたので、共有させていただきたいと思います。
(※ 実務で開発した内容そのままではなく、公開できるように内容を修正しております。)

開発環境

Mac Monteray 12.2.1
CakePHP 4.3.7
PHP 7.4.2
MySQL 5.7.26

本記事記載内容

ユーザ追加時に、ユーザのテーブルだけではなく、関連するその他のテーブルに関しても更新を行う、という方法について記載いたします。
所々解説用にXdebugのスクリーンショットを記載いたします。

DB設計

ER図

20220413_ER図.png

補足

本記事ではusers, affiliation_committees, committees, rolesを利用いたします。
ユーザは複数の委員会に所属可能で、委員会ごとに役割があるとしています。

投入済みデータ

committees
20220513_committees_DB登録データ.png

roles
20220513_roles_DB登録データ.png

コード内容

UsersController.php
    public function add()
    {
        $user = $this->Users->newEmptyEntity();

        if ($this->request->is('post')) {
            # associated の内容を追記                                         
            $user = $this->Users->patchEntity($user, $this->request->getData(), ['associated' => ['AffiliationCommittees']]);
            if ($this->Users->save($user)) {
                $this->Flash->success(__('The user has been saved.'));

                return $this->redirect(['action' => 'index']);
            }
            $this->Flash->error(__('The user could not be saved. Please, try again.'));
        }

        // 部署一覧を取得
        $departments = $this->Users->Departments->find('list', [
            'keyField' => 'id',
            'valueField' => 'department_name'
        ]);
        // 委員会一覧を取得
        $committees = $this->Users->Committees->find('list', [
            'keyField' => 'id',
            'valueField' => 'committee_name'
        ]);
        // 役割一覧を取得
        $roles = $this->Users->Roles->find('list', [
            'keyField' => 'id',
            'valueField' => 'role_name'
        ]);

        $this->set(compact('user', 'departments', 'committees', 'roles'));
    }

注意点
getData() の後にassociated をキーにした連想配列を記載します。
ここに関連するモデルの名称を記載します。

User.php
class User extends Entity
{
    protected $_accessible = [
        'user_name' => true,
        'email' => true,
        'password' => true,
        'department_id' => true,
        'created' => true,
        'modified' => true,
        # POSTした値として受け取れるように下記を追記
        'affiliation_committees' => true,
    ];
}
UsersTable.php
    public function initialize(array $config): void
    {
        parent::initialize($config);

        $this->setTable('users');
        $this->setDisplayField('id');
        $this->setPrimaryKey('id');

        $this->addBehavior('Timestamp');
        # AffiliationSubjects とのアソシエーションを追記
        $this->hasMany('AffiliationCommittees');
    }
add.php
<div class="row">
    <aside class="column">
        <div class="side-nav">
            <h4 class="heading"><?= __('メニュー') ?></h4>
            <?= $this->Html->link(__('ユーザ一覧'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
        </div>
    </aside>
    <div class="column-responsive column-80">
        <div class="users form content">
            <?= $this->Form->create($user) ?>
            <fieldset>
                <legend><?= __('ユーザ追加') ?></legend>
                <?php
                echo $this->Form->control('user_name', ['label' => 'ユーザ名']);
                echo $this->Form->control('email', ['label' => 'Eメールアドレス']);
                echo $this->Form->control('password', ['label' => 'パスワード']);
                echo $this->Form->control('department_id', ['label' => '部署', 'options' => $departments]);
                # 下記2行追記                
                echo $this->Form->control('affiliation_committees.0.committee_id', ['label' => '委員会', 'options' => $committees]);
                echo $this->Form->control('affiliation_committees.0.role_id', ['label' => '権限', 'options' => $roles]);
                ?>
            </fieldset>
            <?= $this->Form->button(__('追加')) ?>
            <?= $this->Form->end() ?>
        </div>
    </div>
</div>

注意点
add.phpで記載している追記の内容は、「テーブル名.要素の番号(0から始める).カラム名」と記載します。

動作確認

下記画像のように入力してから、追加ボタンをクリックします。
20220514_ユーザ追加前.png

Xdebugでデバッグして中身をみてみます。
$this - request - data にPOSTされたデータが入っています。
20220515_POST時Xdebug.png

patchEntityを実行する前の $userの _fiels には何も値が入っていませんが…
20220515_Userエンティティ確認.png

patchEntityを実行した後には下記画像のように値が入っています。
add.php で要素の番号を入れたのはアソシエーションが1対多だからです。
画面の構成上、追加する値が1つだけだったので0という値を入れていました。
逆に言うと、要素の番号を増やせば、1度に大量のデータの更新も可能です。
20220515_Userエンティティ更新後.png

確認

ユーザテーブルに入力した内容のユーザが追加されました。
20220515_ユーザテーブル確認.png
関連するテーブルの方にも同時に追加が行われています。
20220515_所属委員会確認.png

終わりに

ネットで調べると1つのテーブルの追加や編集の方法はすぐにわかるのですが、関連するテーブルもあわせてとなるとなかなかいいものが見つからず、手を焼きました...
ご時世的にPHPのフレームワークといえばLaravelなのかとも思いますが、実務で困っている方のご参考になればと思います。
この他にも実務の中で調査した内容に関しては随時更新していこうと思います。
何かご不明な点があればご連絡のほどよろしくお願いいたします。

0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?