Nick
Nick

Reputation: 8309

CakePHP: Updating multiple records with hasMany

I'm working on a website that has a file management portion where users can create folders and upload files. The folders CAN have subfolders. The folders are not actually created on the file system; they are just in the database. The files are created on the file system and information about the files are in the database.

I'm trying to make it so that if a user deletes a folder, it marks that folder as well as its subfolders and files as deleted. So let's say a user deleted a folder called "Main" that had this structure:

Main

Main\Subfolder\file.txt

Main\Subfolder 2 <-- empty folder

Main\Subfolder 3\image.jpg

I am able to mark all of the folders' deleted field with a "Y" like this:

foreach ($folders_to_delete as $folder_to_delete) {
    $updateAll_conditions['OR'][] = array('id' => $folder_to_delete);
}

$this->UserFolder->updateAll(array('UserFolder.deleted' => "'Y'"), $updateAll_conditions)

But I want to mark all of the folders' deleted field with a "Y" AND all of the files that belong to those folders... with one query. Is that possible?

Upvotes: 1

Views: 971

Answers (1)

Tom Rose
Tom Rose

Reputation: 1589

This problem becomes even more complicated when you consider that a folder might contain another folder!

You ultimately will want a script that can handle file structures of arbitrary complexity.

I suggest running a recursive function over the file structure in question and add the records that need updating to a massive $this->data array.

Then, do a saveAll (or updateAll) on that array.

Here's what a $this-data array might look like for a saveAll with multiple models affected:

$this->data = array(
    'Folder' => array(
        0 => array('deleted' => 'Y'),
        1 => array('deleted' => 'Y'),
    ),
    'File' => array(
        0 => array('deleted' => 'Y'),
        1 => array('deleted' => 'Y'),
    ),
)

I'll keep this answer to the model related stuff, if you want help w/ the recursive function, let's do that that in a separate question.

Upvotes: 1

Related Questions