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 2.3 Model、Controllerの見たい変数の中身をログ出力
CakePHPの Modelや Controllerの変数の中身をログとして出力して見る方法を提供します。
-
CakePHP3でCookieを保存、呼び出し、削除の操作・CakePHP3.7対応
CakePHP3.7でCookieを保存、取り出し、削除する方法を解説。CakePHP3でのCookieの取り扱いはバージョンごとに変更されるため、環境に合わせた方法を探す必要がある。
-
CakePHP 2.3 連携先のテーブルの項目で条件抽出する場合
アソシエーション(連携)している先のテーブルの項目で条件抽出する際の考え方と注意点をサンプルソースを用いて説明しています。
-
CakePHP3のCakeDC/Usersの画面、メール本文テンプレートのカスタマイズ方法解説
CakeDC謹製Usersプラグインの紹介。ユーザ新規登録の流れを紹介しつつテンプレートファイルがどこにあるか、設定情報ファイルがどこにあるか、を説明しつつカスタマイズの方法を解説します。
-
CakePHP3で静的ページの作成は webrootか pagesを使う。トップページを参考に解説
CakePHP3で静的なページを設置する場合の方法(webrootとpagesとを活用する方法)を解説。pagesの解説はデフォルトのトップページがどう表示されているかを参考に解説。ルーティングの機能も。
-
CakePHP4で複数の引数(パラメータ)を付与してコマンドを実行する方法
CakePHP4でコマンドを実行する際に引数(パラメータ)をコマンド内で受け取る処理について解説。複数個の引数にも対応する記述方法も解説。
-
CakePHP3でQRコードを作成、表示するライブラリ「cakePHP-QR-Code-Helper」
CakePHPでQRコードを生成するライブラリ「cakePHP-QR-Code-Helper」の紹介。GDライブラリのインストールも必要ないHelperとして提供されているため、ファイルを設置すればすぐに使用可能。
-
CakePHP3で値を入力直後にバリデーションする方法解説
CakePHP3でバリデーションの実行を保存する時から入力情報を受け取るときに変更する処理の解説。CakePHP3ではnewEntity()の処理でバリデートするため1行追加で対応可能。
-
CakePHP3のcontroller内でテンプレート、レイアウトを変更する際の指定方法
CakePHP3でテンプレートファイルやレイアウトファイルをデフォルトのものから別のものに変更したい場合の指定方法を解説。
-
CakePHP4のCSS、JavaScript、画像のブラウザへのキャッシュをコントロールする
CakePHP4、CakePHP3でブラウザにキャッシュさせる設定の解説。CSS、JavaScript、画像をブラウザにキャッシュさせるのか、定期的にリロードする設定にするのかの設定が可能。
Comment
まさにこの処理を書きたくてググってたら辿り着きました。私は今回のプロジェクトからCakePHP3で開発を始めたんですが、まだ日本語ノウハウの積みあげはこれからっぽい感じなので、すごく助かりました。ありがとうございます!
かみおかさん、コメントありがとうございます!
書いた記事がお役に立ったということで、すごく嬉しいですね。
役に立ったという書き込みをいただくだけで、1週間は頑張って仕事ができます!
引き続き役に立つ記事を書いていきますので、今後もよろしくお願いします!
私もこのコードが書きたくてググりました!
すごくすごく助かりました!ありがとうございます!
rinkoさん、コメントありがとうございます!
役に立ったと言ってもらえるとすごく嬉しいですね。記事を書いた甲斐があった、と思えますからね。
これがベストプラクティスか分かりませんが、引き続き頑張って記事を書いていきますので、今後ともよろしくお願いします!