質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

9462閲覧

CakePHP 3 の複数選択可能なチェックボックスの使い方

phpuser

総合スコア15

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

1クリップ

投稿2016/12/11 09:25

編集2016/12/11 13:46

###前提・実現したいこと

  • CakePHP 3 で、複数選択可能なチェックボックスを使いたい
  • チェックボックスは子テーブル(hasMany の関係のテーブル)の値

###発生している問題・エラーメッセージ

  • validation は動いているのですが、常にエラーになってしまいます

###該当のソースコード
テンプレートでは、以下のようにして子テーブル(sub_tables)の hoge_id を表示しています。

echo $this->Form->input('sub_tables.0.hoge_id', ['multiple' => 'checkbox']);

テンプレートの指定がおかしいのかとおもっているのですが、解決策がみつかりません。
どなたかご教授いただけますと幸いです。

追記

php

1// 親テーブル 2$this->hasMany('HouseRooms', [ 3 'foreignKey' => 'house_id' 4]); 5 6// 子テーブル 7$this->belongsTo('Houses', [ 8 'foreignKey' => 'house_id', 9 'joinType' => 'INNER' 10]); 11$this->belongsTo('MasterRooms', [ 12 'foreignKey' => 'master_room_id', 13]); 14 15// controller 16$house = $this->Houses->newEntity(); 17$house = $this->Houses->patchEntity($house, $request->data, ['associated' => ['HouseRooms']]); 18if ($House->errors()) { 19 $this->Flash->error('入力に誤りがあります。'); 20 return false; 21} 22 23// HouseRoomsTable 24$validator 25 ->integer('master_room_id') 26 ->requirePresence('master_room_id', '部屋を選択してください。') 27 ->notEmpty('master_room_id', '部屋を選択してください。') 28;
// テーブル houses ----- id name ↑ 1:多 ↓ house_rooms ----- id house_id master_room_id master_rooms ----- id name

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

手元では以下のようにしたらできましたよ。Model側をいじらないでやるなら1つのinputでやるのは難しそうでした。もしかしたらできるかもしれませんが

php

1$options = [1 => 'AAA', 2 => 'BBB', 4 => 'CCC']; 2foreach($options as $hoge_id => $name) { 3 echo $this->Form->input("sub_tables.{$hoge_id}.hoge_id", ['type' => 'checkbox', 'label' => $name, 'value' => $hoge_id, 'hiddenField' => false]); 4}

※チェックされたものだけ、小テーブルにレコードができます。

なお、テーブル定義がないのでなんともいえませんが、belongsToManyを使った方が適切なんじゃないかと思いました。

(追記)
以下のバリデーションをHousesTables側に追加すればうまくいかと思いますよ

php

1 public function validationDefault(Validator $validator) { 2 $validator->requirePresence('house_rooms', '部屋を選択してください。'); 3 return $validator; 4 }

投稿2016/12/11 12:01

編集2016/12/11 14:19
popobot

総合スコア6586

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

phpuser

2016/12/11 12:36

ありがとうございます! 試してみたのですが、hoge_id のバリデーションが効きませんでした。 "sub_table.${hoge_id}.hoge_id" の真ん中のところを 0 のままだとバリデーションが効くのですが、連番等にするとダメになってしまいます。
popobot

2016/12/11 12:55

バリデーションが効かないというのはどういうことでしょうか? 保存はできているのでしょうか? また、情報が断片的で状況がよくわかりません。できれば関連するコードも掲載していただけますでしょうか。
phpuser

2016/12/11 13:47 編集

最初の質問にソースコードを追記いたしました。 ご確認くださると幸いです。
phpuser

2016/12/11 13:41

家があって、家に複数の部屋を登録するイメージになります。 部屋は部屋マスタがあって、マスタのIDを登録します。 ここで、部屋がチェックボックスになっていて、1つも選択しなかった場合にエラーにしたいのですが、さきほどのコードだとエラーにならないようです。 反対に、私が書いたコードだと何を選択しても、MasterRoomsTable に定義してある以下のバリデーションに該当してエラーになってしまいます。 $rules->add($rules->existsIn(['master_room_id'], 'MasterRooms'));
popobot

2016/12/11 14:21 編集

状況はだいたい理解しました。回答欄に追記しました。 「1つも選択しなかった場合にエラーにしたい」を実現したいなら、それはHouseテーブル側のバリデートだと思うのそっちに追加してあげればいいと思います。
phpuser

2016/12/12 00:22

追加してみましたが、チェックボックスのバリデーションとして機能していないようでした。
popobot

2016/12/12 02:41

「チェックボックスのバリデーションとして機能していない」とのことですが... 一つもチェックしないと「入力に誤りがあります。」というメッセージは表示されたのでしょうか? 手元の環境ではそこまでは確認しています。 なお、「部屋を選択してください。」というメッセージを出すにはもうひと工夫必要そうでした。
phpuser

2016/12/15 09:08

遅くなり申し訳ありません。 「入力に誤りがあります。」というメッセージも出ておりません。
phpuser

2016/12/15 09:13

私自身、複数選択可能なチェックボックスの使い方がわかっていない状態で質問してしまい申し訳ありません。 公式リファレンス等で参考になる Web サイトがありましたら、ご教示いただけますと大変助かります。
popobot

2016/12/15 12:10 編集

ちょうどいいリファレンスはなさそうですね... テーブル定義をあわせてサンプルコード書いてみようかと思ったのですが、そもそもhasManyではなくbelongsToManyの方がいいと思うのですが、hasManyにしたい理由があるのでしょうか? 例えば、house_roomsに例示されていないカラムが存在するなど
phpuser

2016/12/18 04:08

ありがとうございます。 belongsToMany について自分の理解が間違っていました。 belongsToMany に変更してみます。 また、結果はご報告させていただきます。
popobot

2016/12/18 05:02

belongsToManyだったら、'multiple' => 'checkbox'が使えるはずなので、ぜひやってみてください!
phpuser

2016/12/18 05:13

ありがとうございます! ちょっと出先なので、帰ったらやってみます!
phpuser

2016/12/19 14:25 編集

おかげさまで解決しました! * house_rooms を houses_master_rooms に変更し、houses と master_rooms の連関エンティティ(結合用テーブル)としました。 * houses テーブルの validation に ->requirePresence('master_rooms') を追加しました。 * template は以下のようにしました。 echo $this->Form->input('master_rooms._ids', [ 'options' => $masterRooms, 'multiple' => 'checkbox', 'hiddenField' => false, ]); icchii さんには早い段階から belongsToMany のほうが良いのではとご意見をいただいていたのに、私の理解が間違っていたために時間がかかってしまいました。それにもかかわらず、継続的に回答をいただけて大変助かりました! 本当にありがとうございました!
popobot

2016/12/19 20:57 編集

うまくいってよかったです! 自分の押しが弱かったですね。中間テーブルhouses_master_roomsに追加カラムとかがあるとhasManyの方がよかったりするケースもあるので、深読みしすぎました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問