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
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-
CakePHPで Auto Incrementを外すと Duplicate entry ‘0’ for keyのエラーが出るかも
CakePHPでAuto Incrementの設定を変更したときに「Duplicate entry ‘0’ for key」のエラーが出た。原因はModel内で IDを編集する処理の追加を忘れていたからだった。
-
CakePHP3でデータを保存する save()で発生するエラーを確認する方法を解説
CakePHP3でデータ保存処理のログを取得する方法。save()では true、falseの戻り値しか取得できないが、saveOrFail()と try…catch文を使いエラーログ、エンティティを取得し、不具合の解析を行う。
-
CakePHP3でアソシエーション先のカラムでデータをソートして取得したい
アソシエーション先のテーブルのカラムをキーにソートをしたデータを取得したい!ときの記述方法を解説。「orderAsc()」ではなく「contain()」の中にSort条件を記述する。
-
CakePHP3のユーザ管理・ログイン認証プラグインCakeDC/Usersのインストール解説・3.6以降対応
CakePHP3のユーザ管理プラグイン Usersは、ユーザ登録、メール認証、ログイン認証、ユーザ管理、権限管理、reCAPTCHAなど会員制のサイトを簡単に実現可能。その導入方法、カスタマイズ方法を解説。
-
国際化と地域化の翻訳機能「__()」を使って定数に変数を埋め込む方法
CakePHP4で定数に変数を埋め込み、翻訳機能「__()」で変数に値を入れる方法を紹介。定型の文章の一部だけを置換したい場合に利用すると便利。
-
CakePHP3で「SQLSTATE[23000]: Integrity constraint violation」「SQLSTATE[42S22]: Column not found」などのエラーが出たときの確認するポイント
CakePHP3の開発で発生する「SQLSTATE[23000]: Integrity constraint violation」「SQLSTATE[42S22]: Column not found」のエラーには特有の原因もあるため、その説明と対処方法の解説。
-
CakePHP3でテーブルにカラム(項目)を追加したときに変更するポイントのまとめ
CakePHP3でシステム開発をする際、途中でカラムを追加した場合に何を変更すればいいかを確認。カラムを追加する前後で Bakeした結果を比較し、変更になった点をリストアップした。
-
CakePHP4のController内でViewテンプレート、レイアウトの変更設定を記述する方法
CakePHP4でテンプレートやレイアウトファイルをデフォルトから変更する場合は「render()」を使用するが、記述場所はできるだけコントローラー内の最後の方に書く方がいい。
-
CakePHP3で静的ページの作成は webrootか pagesを使う。トップページを参考に解説
CakePHP3で静的なページを設置する場合の方法(webrootとpagesとを活用する方法)を解説。pagesの解説はデフォルトのトップページがどう表示されているかを参考に解説。ルーティングの機能も。
-
CakePHP 2.3で確認画面付きのお問い合わせフォームの作り方
CakePHPで確認画面付きのお問い合わせフォーム、メールフォームの作り方をサンプルを提示しながら解説。
Comment
まさにこの処理を書きたくてググってたら辿り着きました。私は今回のプロジェクトからCakePHP3で開発を始めたんですが、まだ日本語ノウハウの積みあげはこれからっぽい感じなので、すごく助かりました。ありがとうございます!
かみおかさん、コメントありがとうございます!
書いた記事がお役に立ったということで、すごく嬉しいですね。
役に立ったという書き込みをいただくだけで、1週間は頑張って仕事ができます!
引き続き役に立つ記事を書いていきますので、今後もよろしくお願いします!
私もこのコードが書きたくてググりました!
すごくすごく助かりました!ありがとうございます!
rinkoさん、コメントありがとうございます!
役に立ったと言ってもらえるとすごく嬉しいですね。記事を書いた甲斐があった、と思えますからね。
これがベストプラクティスか分かりませんが、引き続き頑張って記事を書いていきますので、今後ともよろしくお願いします!