データの編集で、同じモデルの複数レコードを一括で編集表示し保存する、ような処理を行ないたいことがよくある。レコード1件1件をその都度編集、保存する手間を省きたい訳だ。
CakePHPのFormヘルパーは、inputエレメントをlabelエレメントやdivエレメントを付けて出力してくれるので、 fieldsetエレメントやlegendエレメントを利用して編集ブロックとしてまとめるなど、CSSを利用して統一したデザインにすることができる。 デザインについては、sdozonoさんの以下の記事が大変参考になった。
Formヘルパーでは、createメソッドにモデル名を設定すれば、後はinputメソッドにテーブルのカラム名を指定し、最後にendメソッド を置いて<form>ブロックの出来上がりである。サーバーにデータがsubmitされた際のactionで は、$this->dataにモデル名とカラム名の配列で入力を取得できるため、そのままモデルのvalidateを利用できるし、saveメソッ ドで保存もできる。
であるわけだが、<input>にid属性を与えるので、あくまでもデータレコード1件では使い勝手が非常に良いのだが、さて同じモデルの複数レコードを一覧で編集したいときはどうすればいいのだろうか?
以下のような使い方ができたので、次回参考のため記録する。
ユーザーのIDと名前の一括編集登録ビューの作成、および保存するアクションを例にする。
function multiedit() { $data = $this->User->find('all'); $this->set(compact('data')); }
multiedit.ctp
<?php echo $form->create('User', array('action'=>'multiedit')); foreach($data['User'] as $key => $user) { echo $form->input("{$key}.id", array('type'=>'hidden', 'value'=>$user['id'])); echo $form->input("{$key}.name", array('value'=>$user['name'])); echo $form->input("{$key}.shimei", array('value'=>$user['shimei'])); } echo $form->end("保存"); ?>
function multiedit() { if (!empty($this->data)) { foreach ($this->data['User'] as $data) { $this->User->save($data); } $this->redirect('index'); } $data = $this->User->find('all'); $this->set(compact('data')); }
今までは、と言うと、ちょっと強引なやり方をしていたようだ。
(CakePHP 1.2.3.8166)