CakePHP

CakePHP Formヘルパーを利用して複数レコードの一括編集と保存

データの編集で、同じモデルの複数レコードを一括で編集表示し保存する、ような処理を行ないたいことがよくある。レコード1件1件をその都度編集、保存する手間を省きたい訳だ。

CakePHPのFormヘルパーは、inputエレメントをlabelエレメントやdivエレメントを付けて出力してくれるので、 fieldsetエレメントやlegendエレメントを利用して編集ブロックとしてまとめるなど、CSSを利用して統一したデザインにすることができる。 デザインについては、sdozonoさんの以下の記事が大変参考になった。

FormHelperとCSS

Formヘルパーでは、createメソッドにモデル名を設定すれば、後はinputメソッドにテーブルのカラム名を指定し、最後にendメソッド を置いて<form>ブロックの出来上がりである。サーバーにデータがsubmitされた際のactionで は、$this->dataにモデル名とカラム名の配列で入力を取得できるため、そのままモデルのvalidateを利用できるし、saveメソッ ドで保存もできる。

であるわけだが、<input>にid属性を与えるので、あくまでもデータレコード1件では使い勝手が非常に良いのだが、さて同じモデルの複数レコードを一覧で編集したいときはどうすればいいのだろうか?

以下のような使い方ができたので、次回参考のため記録する。

ユーザーのIDと名前の一括編集登録ビューの作成、および保存するアクションを例にする。

1.一括表示編集のアクション
先ずはデータの取得部分、保存については以降で検討する。

function multiedit() {
    $data = $this->User->find('all');
    $this->set(compact('data'));
}
2.一括表示編集のビュー
CakePHPで実際に吐き出されたコードを参照すると良い。<input>でname属性を「data[User][0][name]」のように、モデル名の後ろがインクリメントされた番号になるようにするのがキモである。

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("保存");
?>
3.アクションでのデータ保存の部分
$this->dataでアクセスできる配列データは、モデルのfindメソッドで複数件数のデータを取得した時と同様な扱い方ができる。アクションに保存する命令を加える。

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)