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でページごとに読み込むJavaScript、CSSを変える処理の解説
CakePHP3でJavaScriptやCSSを編集する基本形から、それらやテンプレート(エレメント)を特定のテンプレートを読み込んだときのみ編集、実行するための方法、ブロック化について解説。
-
CakePHP 2.3で PDFを作成する方法を調査「mpdf」「TCPDF」「FPDF」
CakePHPで PDFを編集、出力するには「mpdf」「TCPDF」「FPDF」といったプラグインがあり、使い勝手を比較検討しました。TCPDFが一番良さそうでした。
-
CakePHP3のcontroller内でテンプレート、レイアウトを変更する際の指定方法
CakePHP3でテンプレートファイルやレイアウトファイルをデフォルトのものから別のものに変更したい場合の指定方法を解説。
-
CakePHP3のCakeDC/Usersのログイン後のリダイレクトとユーザ権限管理の設定解説
CakeDC謹製Usersプラグインの紹介。ログイン認証後にリダイレクトする先の設定方法についての解説と実運用するために必要なコツを解説。便利な仕組みも仕様の理解があって初めてうまく使いこなせる。
-
CakePHP4の数値項目は「like %10%」の部分一致検索(find select)はできない
CakePHP4でテーブルの数値項目に対してlike句を使用した部分一致検索を実行するとエラーが発生する。クリエービルダーの不具合だと思われ対処方法が分からない。
-
CakePHP 2.3 連携先のテーブルの項目で条件抽出する場合
アソシエーション(連携)している先のテーブルの項目で条件抽出する際の考え方と注意点をサンプルソースを用いて説明しています。
-
CakePHP4のクリエビルダーを使用してOR条件をAND条件でつなぐSQL文を作る方法
CakePHP4のクリエビルダーを使って複数のOR条件をANDでつなぐSQL文を作成する方法を解説。OR条件を記述したwhere句を2つつなげて記述する。
-
CakePHP3でテーブルにカラム(項目)を追加したときに変更するポイントのまとめ
CakePHP3でシステム開発をする際、途中でカラムを追加した場合に何を変更すればいいかを確認。カラムを追加する前後で Bakeした結果を比較し、変更になった点をリストアップした。
-
CakePHP4から外部のデータベースにアクセスする方法解説
CakePHP4のシステムから他のシステムのデータベースにアクセスをし、SQL文を実行する方法を解説。try-catchでエラーを取得する方法も解説。
-
CakePHP4 でコマンドプログラム(シェルプログラム)を作成する方法解説
CakePHP4でバッチ処理を行うためのコマンド・シェルの実装方法について解説。bakeでテンプレートファイルを作成し、「execute()」に処理を記述する方法を解説。
Comment
まさにこの処理を書きたくてググってたら辿り着きました。私は今回のプロジェクトからCakePHP3で開発を始めたんですが、まだ日本語ノウハウの積みあげはこれからっぽい感じなので、すごく助かりました。ありがとうございます!
かみおかさん、コメントありがとうございます!
書いた記事がお役に立ったということで、すごく嬉しいですね。
役に立ったという書き込みをいただくだけで、1週間は頑張って仕事ができます!
引き続き役に立つ記事を書いていきますので、今後もよろしくお願いします!
私もこのコードが書きたくてググりました!
すごくすごく助かりました!ありがとうございます!
rinkoさん、コメントありがとうございます!
役に立ったと言ってもらえるとすごく嬉しいですね。記事を書いた甲斐があった、と思えますからね。
これがベストプラクティスか分かりませんが、引き続き頑張って記事を書いていきますので、今後ともよろしくお願いします!