Another interesting topic was brought up on IRC channel today…
(By the way if you don’t know about the awesome CakePHP IRC channel, you really should visit, it is a great place to get help and learn a thing or two… irc://irc.freenode.net/cakephp)
Anyways, moving on… How do we edit multiple records at once by using the good ol’ saveAll() method?
One immediate problem is that when we do $this->SomeModel->find(‘all’);, the data array is formatted like this:
Array ( [0] => Array ( [Profile] => Array ( [id] => 21 [name] => bob 3 [created] => 2008-10-27 13:01:30 ) ) [1] => Array ( [Profile] => Array ( [id] => 20 [name] => larry 5 [created] => 2008-10-27 13:01:30 ) )
However, we know that in order for saveAll() to work correctly the data should be formatted like this:
[Profile] => Array ( [21] => Array ( [id] => 21 [name] => bob 3 [created] => 2008-10-27 13:01:30 ) [20] => Array ( [id] => 20 [name] => larry 5 [created] => 2008-10-27 13:01:30 )
Notice the difference of the key placement and the array structure?
Alright, let’s examine a super-easy way to get what we need by using the lovely Set class, and namely the Set::combine() method.
First, we build our edit action keeping in mind that we need the data in a form to follow a specific format for saveAll():
[code language=”html”]
function edit() {
if(!empty($this->data)) {
$this->Profile->saveAll($this->data[‘Profile’]);
}
else {
$this->data[‘Profile’] = Set::combine($this->Profile->find(‘all’), ‘{n}.Profile.id’, ‘{n}.Profile’);
}
}
[/cc]
We use Set::combine() to easily reformat the return of find(‘all’) (to look just like an example array above) and, of course, assign it to $this->data, which is going to be used by the Form Helper.
Now, all we need to do is build our form (let’s make something really simple):
[code language=”php”]
echo $form->create(‘Profile’, array(‘action’=>’edit’));
foreach($this->data[‘Profile’] as $key => $value) {
echo $form->input(‘Profile.’.$key.’.name’);
echo $form->input(‘Profile.’.$key.’.id’);
}
echo $form->end(‘Save All Profiles’);
[/cc]
This form allows us to rename multiple Profiles at once. It is built from our $this->data array and follows exactly the right format, which allows the saveAll() method to work correctly.