組み込みのソリューションがあるとは思いません。動作するコードを思いつきましたが、複数のコントローラー アクションで使用できるように、それを独自の関数に入れたいと思うでしょう。また、完璧ではありません。たとえば、CakePHP では日付フィールドがselect
s としてフォームにレンダリングされるため、日付フィールドでは失敗します。
これは編集アクション用です。元のコード:
public function edit($id = null) {
$this->User->id = $id;
if (!$this->User->exists()) {
throw new NotFoundException(__('Invalid user'));
}
if ($this->request->is('post') || $this->request->is('put')) {
if ($this->User->save($this->request->data)) {
$this->Session->setFlash(__('The user has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The user could not be saved. Please, try again.'));
}
} else {
$this->request->data = $this->User->read(null, $id);
}
}
変更されたコード:
public function edit($id = null) {
$this->User->id = $id;
if (!$this->User->exists()) {
throw new NotFoundException(__('Invalid user'));
}
if ($this->request->is('post') || $this->request->is('put')) {
$originalData = unserialize(base64_decode($this->request->data['Extra']['original_data']));
$save = $this->request->data;
unset($save['Extra']);
foreach ($save as $model => $modelFields) {
if (!array_key_exists($model, $originalData)) {
continue;
}
foreach ($modelFields as $field => $value) {
if (!array_key_exists($field, $originalData[$model])) {
continue;
}
if ($save[$model][$field] === $originalData[$model][$field]) {
unset($save[$model][$field]);
}
}
}
$this->User->set($save);
if ($this->User->validates() && $this->User->save($save, false)) {
$this->Session->setFlash(__('The user has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The user could not be saved. Please, try again.'));
}
} else {
$this->request->data = $this->User->read(null, $id);
$this->request->data['Extra']['original_data'] = base64_encode(serialize($this->request->data));
}
}
また、これを のフォームのどこかに追加しedit.ctp
ます。
echo $this->Form->hidden('Extra.original_data');