CakePHP3で他のテーブルのマスタテーブルからセレクトボックス(プルダウンリスト)を作る
2019/07/22
CakePHP3で他のテーブルのマスタテーブルからセレクトボックスを作る
マスタのテーブルを作成し、そのマスタテーブルの情報を基にしてセレクトボックス(プルダウンリスト)を作成する方法を解説します。
具体的には、下記の「Master Roles(権限マスタ)」の項目をテーブルから取得するイメージです。
想定しているテーブル
想定しているテーブルは、以下の「ユーザテーブル」と「権限マスタテーブル」です。
ユーザ情報に、権限マスタから権限情報を編集できるようにしたのち、ユーザ認証機能を実装し、ユーザの持つ権限によって利用できる機能、できない機能を振り分けることを想定しています。
そのために、ユーザ情報の登録の際に「権限」をプルダウン(セレクトボックス)で選択できるようにする、というのが趣旨になります。
【ユーザテーブル】
1 2 3 4 5 6 7 8 9 |
CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, `username` varchar(255) NOT NULL, `password` varchar(255) NOT NULL, `master_roles_id` char(2) NOT NULL, `email` varchar(255) NOT NULL, `created` datetime NOT NULL, `modified` datetime NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
【権限マスタ】
1 2 3 4 5 6 7 |
CREATE TABLE `master_roles` ( `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, `name` varchar(255) NOT NULL, `delete_flag` char(1) DEFAULT NULL, `created` datetime NOT NULL, `modified` datetime NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
想定しているテーブルは上記のような形で、「ユーザテーブル」の 4項目目に「権限マスタ」の IDを編集することを想定しています。
セレクトボックスを作成するサンプルプログラム
基本的な処理は「cake bake all users」コマンドで生成しています。
そのうえで、加える処理についての解説です。
/src/Controller/UsersController.php の変更
下記のとおり、コントローラーの最初の方に「use Cake\ORM\TableRegistry;
」を追記します。
これを追記することで、コントローラーに関連しない他のテーブルの情報を取得することができるようになります。
1 2 3 4 5 |
<?php namespace App\Controller; use App\Controller\AppController; use Cake\ORM\TableRegistry; // この行を追記します。 |
続いて、「UsersController」の中に「initialize()」関数を追加します。
7行目の「master_roles」が読み込むテーブル名になり、複数ある場合は複数行記述します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class UsersController extends AppController { // 以下の「initialize()」を追加します。 // 3.6.0 以降の場合 public function initialize(){ parent::initialize(); $this->MasterRoles = TableRegistry::getTableLocator()->get("master_roles"); } // 3.6.0 より前の場合 public function initialize(){ parent::initialize(); $this->MasterRoles = TableRegistry::get("master_roles"); } |
2019.07.22 追記
CakePHP3.6から、TableRegistryクラスの使用方法が変更になりました。
そのため、上記のサンプルコードでは両方を併記しています。
続いて、「initialize()」のすぐ後ろに「beforeFilter()」を追加します。
1 2 3 4 5 6 7 8 9 10 11 |
// 以下の「beforeFilter()」を追加します。 public function beforeFilter(){ $masterRolesAll = $masterRolesVaild = array(); foreach ($this->MasterRoles->find()->all() as $tmp){ $masterRolesAll += array ($tmp->id => $tmp->name); if ($tmp->delete_flag != "1"){ $masterRolesVaild += array ($tmp->id => $tmp->name); } } $this->set(compact("masterRolesAll","masterRolesVaild")); } |
上記は、「delete_flag」の有無によって変数を 2つに分けています。
プルダウンの生成には、「delete_flag」がないもののみを使いますので、「$masterRolesVaild」の方を使います。
ですが、すでにマスタを削除していても、そのマスタの値を持つレコードが残っている可能性がある場合などは、「$masterRolesAll」を使う場合があるのではないか、と思い作成しています。
マスタを削除する際に、そのマスタのコードを利用しているレコードをチェックするなど、マスタ管理がしっかりできていてる場合は「$masterRolesVaild」の方だけあれば足りるでしょう。
ちなみに、ここでのサンプルは、権限マスタから全件取得したうえで、プログラムの処理として、「delete_flag」の値で振り分け処理をしています。
ですが、そもそも権限マスタテーブルから値を取得する際に「delete_flag」によって振り分けたレコードを取得する場合は、下記の様に where句を追加することも可能です。
1 2 3 |
$this->MasterRoles->find()->all() ↓変更 $this->MasterRoles->find()->where(["master_roles.delete_flag is" => null] |
また、「$masterRolesAll」「$masterRolesVaild」の変数を「beforeFilter()」で作成しています。
これは、Usersコントローラーの中のすべてのアクションで使えるようにするためです。(今回は、index、add、editで使うためです。)
特定のアクションだけで使えればいい場合は、3~10行目を特定のアクションの中に移しても問題ありません。
/src/Template/Users/index.ctp の変更
index.ctpは、以下のように変更します。
ここでは、一覧表示する際に、権限コードを表示するのではなく、権限名称を表示するようにしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// 変更前 <td><?= h($user->master_roles_id) ?></td> // 変更後 <td> <?php if ($user->master_roles_id){ if (isset($masterRolesVaild[$user->master_roles_id])){ echo $masterRolesVaild[$user->master_roles_id]; } } ?> </td> |
/src/Template/Users/add.ctp の変更
/src/Template/Users/edit.ctp の変更
add.ctp、edit.ctpは以下のように変更します。
新規登録、更新の画面では、プルダウンで権限を選択できるようにしています。
セレクトボックス(プルダウン)に編集する値は、「options」に連想配列で、キーと値を渡すだけで作成してくれます。
1 2 3 4 5 6 7 |
// 変更前 echo $this->Form->input('master_roles_id'); // 変更後 echo $this->Form->input('master_roles_id', ["type"=>"select","empty"=>"選択してください", "options"=>$masterRolesVaild]); |
CakePHP3の Form Helperの使い方については、「CakePHP3のForm Helperの使い方のまとめ」に記事を書いていますので参照してください。
上記の Form Helperの使い方を読んでもらえば分かりますが、プルダウンリスト(セレクトボックス)をラジオボタン変えたい場合は、「"type"=>"select"
」を「"type"=>"radio"
」にすれば OKです。
また、「"empty"=>"選択してください"
」は、最初に nullの値を入れる場合の設定です。
今回の紹介している「権限」は必須項目となるべき項目ですので、「"empty"=>"選択してください"
」は消す方が無難かもしれません。
また、先ほどの「"type"=>"select"
」を記述しなくてもデフォルトでプルダウンリストになりますので、下記の様に短く記述することも可能です。
1 2 |
echo $this->Form->input('master_roles_id', ["options"=>$masterRolesVaild]); |
取得したテーブルの値のオブジェクトを配列にする方法
今回は、UsersController.phpで配列を生成するという仕組みで構築しましたが、テーブルから取得した値をオブジェクトのまま View側に渡す場合もあるかと思います。
そんな時、特定のレコードを自由に扱えるようにするには配列にする必要があるのだと思いますが、その方法について調べた内容を下記の記事にしていますので、あわせて参考にしてください。
CakePHP3のビューで受取ったテーブルのオブジェクトを連想配列に変換する方法
CakePHP3の関連記事
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にOGPをfetch、asignを利用してテンプレートごとに指定する方法を解説
その他の「CakePHP3」に関する記事一覧
GoogleAdwords
GoogleAdwords
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-
-
CakePHP3でモデルなしフォームからCSVをアップロードしレコードを更新する方法解説
CakePHP3でCSVファイルをアップロードしレコードを追加、更新する処理の作成方法の解説。モデルとは直接関連しないフォームからCSVファイルをアップロードするため汎用的に使用可能。
-
-
MySQL+CakePHPのdate型、datetime型項目は「2999-12-31」までしか扱えない
CakePHPの日付、日時の型であるdate型、datetime型の最大値は2999-12-31となっている。MySQLは9999年までなので違いがあるので注意が必要だ。
-
-
CakePHP3でkeywords、DescriptionをHTMLヘルパーを使って設定する
CakePHP3のkeywordsとdescriptionを設定する方法の解説。CakePHP3にはmetaタグを編集するHTMLヘルパーが用意されているためそれを利用すればOK!ポイントはブロック化を有効にすること。
-
-
CakePHP4のCakeDC/Usersの Usersへの接続、バリデーションのカスタマイズ方法解説
CakeDC謹製Usersプラグインの紹介。CakePHP4で使う場合のUsersのカスタマイズとして入力項目のバリデーションの変更を、プラグインのファイルは触らずオーバーライドにより実装する方法を解説する。
-
-
CakePHPを学ぶ際にはオブジェクト指向を学ぼう
CakePHPはオブジェクト指向で書かれていますので、CakePHPを学ぶにはオブジェクト指向も学びましょう。
-
-
CakePHP4で「app_local.php」「.env」を利用して環境ごとの定数を振り分ける方法
CakePHP4で.env、app_local.phpに定数を定義してそれを呼び出す方法の解説。Gitでは管理せず本番環境と開発環境とで異なる定数を定義するためそれを利用する方法。
-
-
CakePHP3の1対多での連携を中間テーブルを使った多対多の連携に変更するときの手順
CakePHP3で「1対多」の連携を中間テーブルを利用した「多対多」の連携に変更するときの手順のまとめ。中間テーブルの設定やModelの変更などを間違いやすい箇所を指摘しながらの解説。
-
-
CakePHP3のルーティング(routes.php)の変更が反映されない時はキャッシュのクリアを
CakePHP3でルーティングの設定変更をしたけど反映されない!そんなときは慌てず騒がずキャッシュをクリアしよう!ルーティングの設定もキャッシュされることがあるらしい。
-
-
CakePHP4のFrozenDateで1ヵ月前、先月、今月1日、来月末の日付などを算出する方法
CakePHPには「FrozenDate」の日付を扱う関数が用意されている。これを利用して、1ヶ月後、月末日、月初日、5日後などを指定して日付を取得できる。それを解説。
-
-
CakePHP 2.3 Search Pluginで検索処理 その2表示件数を動的に変える方法
CakePHPの検索プラグイン Search Pluginの検索処理の中で動的に表示件数を変える方法です。
Comment
まさにこの処理を書きたくてググってたら辿り着きました。私は今回のプロジェクトからCakePHP3で開発を始めたんですが、まだ日本語ノウハウの積みあげはこれからっぽい感じなので、すごく助かりました。ありがとうございます!
かみおかさん、コメントありがとうございます!
書いた記事がお役に立ったということで、すごく嬉しいですね。
役に立ったという書き込みをいただくだけで、1週間は頑張って仕事ができます!
引き続き役に立つ記事を書いていきますので、今後もよろしくお願いします!
私もこのコードが書きたくてググりました!
すごくすごく助かりました!ありがとうございます!
rinkoさん、コメントありがとうございます!
役に立ったと言ってもらえるとすごく嬉しいですね。記事を書いた甲斐があった、と思えますからね。
これがベストプラクティスか分かりませんが、引き続き頑張って記事を書いていきますので、今後ともよろしくお願いします!