エス技研

WordPress、CakePHP、PHP、baserCMSなどの Web系システムを中心に情報を提供します!


CakePHP3でテーブルにカラム(項目)を追加したときに変更するポイントのまとめ

      2019/06/08

CakePHP3でテーブルにカラムを追加したときに変更するポイント

 

システム開発途中でカラムの追加はよくある話

 
CakePHP3でシステムを開発するとき、Bakeを使ってベースとなる処理を作成しておくと作業を効率化することができます。
 
 
ですが、システム開発においては、途中でテーブルにカラムを追加する必要性が生まれることは日常茶飯事です。
 
開発があまり進んでいないときならば、テーブルにカラムを追加して Bakeからやり直す、という方法もありですが、相応に開発が進んでいたら、Bakeからやり直すのは非効率的ですし、バグが混入することにもなりかねません。
 
 
というわけで、テーブルにカラムを追加する前と後とで、Bakeして生成される Controller、Model、Templateファイルがどう変わるのか、を確認して、カラムを追加したときは何を変更すべきなのか、を明確にしていきます。
 
これを見て変更点をチェックすれば、カラムを追加しても抜けもれなく対応できます!
(処理の内容を理解していれば、修正すべき個所は分かるハズではあるんですが...)
 
 

作成するテーブルのサンプル

 
まず、最初に作成したテーブルは下記のとおりです。
 

CREATE TABLE `tests` (
 `id`          int(11) unsigned NOT NULL AUTO_INCREMENT,
 `user_id`     char(36)         NOT NULL,
 `url`         varchar(100)     NOT NULL,
 `new_url`     varchar(100)     NOT NULL,
 `created`     datetime         NOT NULL,
 `modified`    datetime         NOT NULL,
 PRIMARY KEY (`id`),
 UNIQUE KEY `new_url_text` (`new_url`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

 
これに対して、下記の ALTER TABLEで削除フラグのカラム「deleted」を追加します。
 

ALTER TABLE tests ADD deleted tinyint default null AFTER new_url;

 
 

Bakeで作成されるファイル

 
Bakeを実行して作成されるファイルは、以下となります。
Bakeを再実行する際に「Do you want to overwrite? (y/n/a/q)」との確認があるファイルでもあります。
 
/src/Model/Table/TestsTable.php
/src/Model/Entity/Test.php
/tests/Fixture/TestsFixture.php
/tests/TestCase/Model/Table/TestsTableTest.php
/src/Controller/TestsController.php
/tests/TestCase/Controller/TestsControllerTest.php
/src/Template/Tests/index.ctp
/src/Template/Tests/view.ctp
/src/Template/Tests/add.ctp
/src/Template/Tests/edit.ctp
 
 
更新された内容は以下の通りとなります。
 

/src/Model/Entity/Test.php

 
13行目のコメント行が追加になっています。

 * @property int|null $deleted

 
34行目が追加になっています。

        'deleted' => true,

 
 

/src/Model/Table/TestsTable.php

 
74、75行目が追加になっています。

        $validator
            ->allowEmptyString('deleted');

 
 

/src/Template/Tests/index.ctp

 
24行目が追加になっています。

                <th scope="col"><?= $this->Paginator->sort('deleted') ?></th>

 
37行目が追加になっています。

                <td><?= $this->Number->format($test->deleted) ?></td>

 
 

/src/Template/Tests/view.ctp

 
38~41行目が追加になっています。

            <th scope="row"><?= __('Deleted') ?></th>
            <td><?= $this->Number->format($test->deleted) ?></td>
        </tr>
        <tr>

 
 

/src/Template/Tests/add.ctp

 
23行目が追加になっています。

            echo $this->Form->control('deleted');

 
 

/src/Template/Tests/edit.ctp

 
29行目が追加になっています。

            echo $this->Form->control('deleted');

 
 

/tests/Fixture/TestsFixture.php

 
22行目が追加になっています。

        'deleted' => ['type' => 'tinyinteger', 'length' => 4, 'unsigned' => false, 'null' => true, 'default' => null, 'comment' => '', 'precision' => null],

 
42~52行目の、48行目が追加、45、49、50行目が変更になっています。

        $this->records = [
            [
                'id' => 1,
                'user_id' => 'bc984858-445f-4cc1-adff-65441c360e2e',
                'url' => 'Lorem ipsum dolor sit amet',
                'new_url' => 'Lorem ipsum dolor ',
                'deleted' => 1,
                'created' => '2019-04-11 22:37:23',
                'modified' => '2019-04-11 22:37:23'
            ],
        ];

 
 
テーブルの構造を変更しても、Controllerは変更されていません。
テーブル構造を変更した場合の対応は、Modelの Entityと Tableのファイルでした。
 
Templateも変更がありますが、こちらは、必要に応じて項目を追加するといいでしょう。
 
 

テーブル構造を変更した場合はキャッシュをクリアする

 
テーブルの構造を変更した場合は、キャッシュをクリアしましょう。
 
キャッシュのクリア方法は、CakePHP 3.3以降であれば、下記のコマンドが便利です。

$ bin/cake cache clear_all

 
詳しくは、「CakePHP3、CakePHP4のキャッシュをクリアする方法「bin/cake cache clear_all」を使う」に記事を書いていますので、参考にしてください。
 
 

関連テーブルがある時、ない時とでの記述内容の違い

 
アソシエーションしたテーブル(関連付けされたテーブル)がある場合は、関連テーブルを createする前に bakeする場合と、createしてから bakeした場合とでも作成されるファイルがやや違うことも確認しました。
 
 
差異があるファイルの内容は、以下の通りです。
 

/src/Template/Tests/add.ctp

 

    <ul class="side-nav">
        <li class="heading"><?= __('Actions') ?></li>
        <li><?= $this->Html->link(__('List Tests'), ['action' => 'index']) ?></li>
        <li><?= $this->Html->link(__('List Users'), ['controller' => 'Users', 'action' => 'index']) ?></li>
        <li><?= $this->Html->link(__('New User'), ['controller' => 'Users', 'action' => 'add']) ?></li>
    </ul>

 
上記の 4、5行目が追加になっています。
これは、「add.ctp」の 17行目、18行目ですが、「Tests」の画面でも「Users」への関連リンクが追加されています。
 
 

            echo $this->Form->control('user_id', ['options' => $users]);
            echo $this->Form->control('url');
            echo $this->Form->control('new_url');

 
また、上記の 1行目も下記のように変更されています。
 

            // 変更前
            echo $this->Form->control('user_id');

            // 変更後
            echo $this->Form->control('user_id', ['options' => $users]);

 
画面を表示させると分かるのですが、変更前はテキスト形式の入力ボックスなのですが、変更後はプルダウン形式に変更されています。
 
add.ctpと同じ様に、edit.ctp、index.ctp、view.ctpも同じような趣旨の変更が加わっています。
 
 

/src/Model/Entity/Test.php

 
16行目のコメントが下記のように変更になっています。

// 変更前
 * @property \App\Model\Entity\User $user

// 変更後
 * @property \CakeDC\Users\Model\Entity\User $user

 
 

/src/Model/Table/TestsTable.php

 
12行目のコメントが下記のように変更になっています。

// 変更前
 * @property \App\Model\Table\UsersTable|\Cake\ORM\Association\BelongsTo $Users

// 変更後
 * @property \CakeDC\Users\Model\Table\UsersTable|\Cake\ORM\Association\BelongsTo $Users

 
 

/tests/Fixture/TestsFixture.php

 
/tests/Fixture/TestsFixture.php も更新されていましたが、44、47、48行目のデータの値でしたので、ここでの説明は割愛します。
 
 
関連テーブルを作成する前後での違いを検証するつもりはありませんでした。
ですが、「tests」に CakeDC/Usersの user_idと連携させるためのカラムがあることを忘れていて、「tests」だけで Bakeをしてしまったため、「『user_id』に関連するテーブルがない」というエラーが表示されてしまいました。
 
そのため、ついでに確認をしてみることにした次第です。
 
 

CakePHP3の関連記事

CakePHPのpostlinkで生成した削除リンクをクリックしても処理が実行されない対処法
CakePHP4のCSS、JavaScript、画像のブラウザへのキャッシュをコントロールする
CakePHP3でレコードを保存(追加、更新、Insert、Update)する複数の方法を紹介
CakePHP3でモデルなしフォームからCSVをアップロードしレコードを更新する方法解説
CakePHP3でPHP Simple HTML DOM Parserを使ってスクレイピングする方法
CakePHP3のInsert On Duplicate Key Update(upsert)構文を解説・バルク処理も
CakePHP3の1対多での連携を中間テーブルを使った多対多の連携に変更するときの手順
CakePHP3でデフォルトのソート条件を設定してユーザの選択肢たソート条件を有効にする方法
CakePHP3で Ajaxを使う方法の解説。3.6以降対応。Successとthenの両方を解説。
CakePHP3でパンくずの指定は HTMLヘルパーを使って指定する方法を解説
 
その他の「CakePHP3」に関する記事一覧
 
 

 - CakePHP 3.x 4.x 5.x

最後までお読みいただきましてありがとうございます。
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!

Message

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

下記の空欄を埋めてください。 * Time limit is exhausted. Please reload CAPTCHA.

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

※入力いただいたコメントは管理者の承認後に掲載されます。

  関連記事

CakePHP3で生の SQLの実行はConnectionManagerを使う
CakePHP3で生の SQLの実行はConnectionManagerを使う

CakePHP3で生の SQL文を実行する方法を解説。クリエビルダーを使う場合は TableRegistryを利用するが、SQLを実行する場合は ConnectionManagerを使う。プリペアードステートメントの使用方法も解説。

CakePHP3のビューで受取ったテーブルのオブジェクトを連想配列に変換する方法
CakePHP3のビューで受取ったテーブルのオブジェクトを連想配列に変換する方法

コントローラーからビューに送ったテーブルのオブジェクトを連想配列に変換し、ビューの中で自由に使えるようにするメソッド「toArray()」の解説。連想配列に変換できれば利用度アップ!

CakePHP3のCakeDC/Users、Authでログインなしでもアクセスを許可する設定
CakePHP3のCakeDC/Users、Authでログインなしでもアクセスを許可する設定

CakePHP3の Authコンポーネントや CakeDC/Usersプラグインなどを利用したユーザ管理・認証システムにおいて、ログインしていなくても見ることができるページの設定方法を解説。

CakePHP4の定数定義ファイルを環境変数によって本番と開発を振り分ける方法解説
CakePHP4の定数定義ファイルを環境変数によって本番と開発を振り分ける方法解説

CakePHP4で開発環境と本番環境とで違う設定ファイルを読み込ませて環境ごとに定数を切り替える方法を解説。Apacheのhttpd.confに環境変数を設定しそれを読み込み判別する。

CakePHP3でWarning Error: SplFileInfo::openFile()エラーが発生した場合の対処方法
CakePHP3でWarning Error: SplFileInfo::openFile()エラーが発生した場合の対処方法

CakePHP3のキャッシュファイルのパーミッションエラー Error: SplFileInfo::openFile()が発生した場合の対応方法解説。app.phpにキャッシュファイルのパーミッション設定を行い、既存のファイルは削除。

CakePHP3チュートリアルで日付と時刻のDateTimeでエラーが出たときの対処方法
CakePHP3チュートリアルで日付と時刻のDateTimeでエラーが出たときの対処方法

CakePHP3のブックマークチュートリアルには記載ミスもあり、そのまま動かない個所もある。CakePHP3では namespaceを使うようになったので、classを呼び出すときに¥を追加する必要が!

CakePHP3の更新画面でUpload Plugin 3.0を使う方法、viewで使う方法解説・その3
CakePHP3の更新画面でUpload Plugin 3.0を使う方法、viewで使う方法解説・その3

CakePHP3でファイル、画像をアップロードするプラグイン、upload plugin 3を導入する手順を解説した記事。3部作のその3で記事を更新する際のファイルの取り回しなどについてを解説。

CakePHP4のユーザ管理・ログイン認証プラグインCakeDC/Usersのインストール解説
CakePHP4のユーザ管理・ログイン認証プラグインCakeDC/Usersのインストール解説

CakePHP4のユーザ管理プラグイン Usersは、ユーザ登録、メール認証、ログイン認証、ユーザ管理、権限管理、reCAPTCHAなど会員制のサイトを簡単に実現可能。その導入方法、カスタマイズ方法を解説。

CakePHP5でヘルパーから他のヘルパーを読み込む方法・CakePHP4からの変更点
CakePHP5でヘルパーから他のヘルパーを読み込む方法・CakePHP4からの変更点

CakePHP5のヘルパーで他のヘルパーを読み込む方法を解説。公式の日本語CookbookはCakePHP4のソースのままで間違っているため注意が必要。CakePHP4からの移行の際も同じ点に注意が必要。

CakePHP3で静的ページの作成は webrootか pagesを使う。トップページを参考に解説
CakePHP3で静的ページの作成は webrootか pagesを使う。トップページを参考に解説

CakePHP3で静的なページを設置する場合の方法(webrootとpagesとを活用する方法)を解説。pagesの解説はデフォルトのトップページがどう表示されているかを参考に解説。ルーティングの機能も。