前提
前提として以下のような場合のテーブルでHABTMの設定をしているとします。
テーブルのリレーション
モデル
good.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <?php class Good extends AppModel { var $name = 'Good' ; var $hasAndBelongsToMany = array ( 'Tag' => array ( 'className' => 'Tag' , 'joinTable' => 'goods_has_tags' , 'with' => 'GoodsHasTag' , 'foreignKey' => 'good_id' , 'associationForeignKey' => 'tag_id' , 'conditions' => array ( 'Tag.deleted' => null, ), 'unique' => true, ) ); var $validate = array ( 'id' => array ( 'notempty' ), ); } ?> |
tag.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <?php class Tag extends AppModel { var $name = 'Tag' ; var $hasAndBelongsToMany = array ( 'Good' => array ( 'className' => 'Good' , 'joinTable' => 'goods_has_tags' , 'with' => 'GoodsHasTag' , 'foreignKey' => 'tag_id' , 'associationForeignKey' => 'good_id' , 'conditions' => array ( 'Good.deleted' => null, ), 'unique' => true, ) ); var $hasMany = array ( 'GoodsHasTag' => array ( 'className' => 'GoodsHasTag' , 'foreignKey' => 'tag_id' , ) ); var $validate = array ( 'id' => array ( 'notempty' ), ); } ?> |
goods_has_tag.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <?php class GoodsHasTag extends AppModel { var $name = 'GoodsHasTag' ; var $belongsTo = array ( 'Good' => array ( 'className' => 'Good' , 'foreignKey' => 'good_id' , 'conditions' => array ( 'Good.deleted' => null, ), 'unique' => true, 'fields' => '' , 'order' => '' ), 'Tag' => array ( 'className' => 'Tag' , 'foreignKey' => 'tag_id' , 'conditions' => array ( 'tag.deleted' => null, ), 'unique' => true, 'fields' => '' , 'order' => '' ) ); } ?> |
※deletedは削除用フラグ
チェックボックス作成用のソースコード
コントローラー
1 2 3 4 5 6 7 | function add(){ $this ->set( 'tags' , $this ->Good->Tag->find( 'list' , array ( 'conditions' => array ( 'Tag.deleted' => null, )))); ... } |
ビュー
1 2 3 | <?php echo $form ->input( 'Tag' , array ( 'multiple' => 'checkbox' , 'label' => 'タグ' )); ?> |
このように書いておけば、例えば更新画面の場合は$this->dataに入ってるデータをデフォルトでチェックつけた状態で表示されますし。登録の際に$this->Good->saveAll($this->data);とすればgoods_has_tagsテーブルも更新されます。(更新の場合はDELETE、INSERTされます)
個人的にはHABTMでデータ持つのは面倒な気がしていてあまり好きじゃないので、多対多の場合はカンマ区切りで文字列でデータを持たせるように作ってます。
(goodsの場合だと、goods.tagのようなフィールドを作って文字列で)
文字列で持たせる場合も、以下のコードでチェックボックスを作成できます。
1 2 3 | <?php echo $form ->input( 'tag' , array ( 'type' => 'select' , 'multiple' => 'checkbox' , 'options' => Invariable:: $TAG_TYPES , 'value' => explode ( ',' , $this ->data[ 'Good' ][ 'tag' ]), 'label' => 'タグ' )); ?> |
※タグは定数Invariable::$TAG_TYPESで管理。