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.