Editing multiple records with saveAll()

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.

%d bloggers like this: