cakephp icon indicating copy to clipboard operation
cakephp copied to clipboard

Allow preserving keys when using select loaders.

Open ADmad opened this issue 1 year ago • 1 comments

Setting the preserveKeys option for the association's finder query now preserves the record keys when populating the associated records array for the parent records.

Refs #10118

ADmad avatar Aug 28 '24 06:08 ADmad

I am open to renaming the option (preserveIndex for e.g.) and/or prefixing it with underscore to indicate it's a special core option.

ADmad avatar Aug 28 '24 06:08 ADmad

I thought of an alternative which would avoid requiring a query option. We keep the existing keys if the results array is not a list:

diff --git a/src/ORM/Association/Loader/SelectLoader.php b/src/ORM/Association/Loader/SelectLoader.php
index 4dc682e5ad..88fcbbc461 100644
--- a/src/ORM/Association/Loader/SelectLoader.php
+++ b/src/ORM/Association/Loader/SelectLoader.php
@@ -485,16 +485,26 @@ class SelectLoader
             $this->bindingKey;
         $key = (array)$keys;
 
-        foreach ($fetchQuery->all() as $result) {
+        $results = $fetchQuery->all()->toArray();
+        $preserveKeys = !array_is_list($results);
+
+        foreach ($results as $i => $result) {
             $values = [];
             foreach ($key as $k) {
                 $values[] = $result[$k];
             }
+
             if ($singleResult) {
                 $resultMap[implode(';', $values)] = $result;
-            } else {
-                $resultMap[implode(';', $values)][] = $result;
+                continue;
             }
+
+            if ($preserveKeys) {
+                $resultMap[implode(';', $values)][$i] = $result;
+                continue;
+            }
+
+            $resultMap[implode(';', $values)][] = $result;
         }
 
         return $resultMap;

ADmad avatar Aug 29 '24 08:08 ADmad