diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Action.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Action.php index 2a34c8979b..efd3f4ed6f 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Action.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Action.php @@ -261,7 +261,9 @@ abstract class Action extends DatabasesAction $relationId = $relation->getAttribute('$id'); } elseif (\is_string($relation)) { $relationId = $relation; - } elseif (!(\is_array($relation) && \array_values($relation) !== $relation)) { + } elseif (\is_array($relation) && \array_values($relation) !== $relation) { + $relationId = $relation['$id'] ?? null; + } else { throw new Exception(Exception::RELATIONSHIP_VALUE_INVALID, 'Relationship value must be an object or document ID string, not ' . \gettype($relation)); } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Create.php index 8927c6b27b..253cf8ec3c 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Create.php @@ -309,10 +309,19 @@ class Create extends Action ); foreach ($relations as &$relation) { + // Generate unique ID for new relation without $id + if ( + \is_array($relation) + && \array_values($relation) !== $relation + && !isset($relation['$id']) + ) { + $relation['$id'] = ID::unique(); + } + $this->validateRelationship($relation); + // If the relation is an array it can be either update or create a child document. if (\is_array($relation) && \array_values($relation) !== $relation) { - $relation['$id'] = ID::unique(); $relation = new Document($relation); } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Update.php index 0f3eb9e026..34f2a45e15 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Update.php @@ -201,10 +201,19 @@ class Update extends Action ); foreach ($relations as &$relation) { + // Generate unique ID for new relation without $id + if ( + \is_array($relation) + && \array_values($relation) !== $relation + && !isset($relation['$id']) + ) { + $relation['$id'] = ID::unique(); + } + $this->validateRelationship($relation); + // If the relation is an array it can be either update or create a child document. if (\is_array($relation) && \array_values($relation) !== $relation) { - $relation['$id'] = ID::unique(); $relation = new Document($relation); } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Upsert.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Upsert.php index cdff15c5ab..8b500a9e61 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Upsert.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Upsert.php @@ -211,10 +211,19 @@ class Upsert extends Action ); foreach ($relations as &$relation) { + // Generate unique ID for new relation without $id + if ( + \is_array($relation) + && \array_values($relation) !== $relation + && !isset($relation['$id']) + ) { + $relation['$id'] = ID::unique(); + } + $this->validateRelationship($relation); + // If the relation is an array it can be either update or create a child document. if (\is_array($relation) && \array_values($relation) !== $relation) { - $relation['$id'] = ID::unique(); $relation = new Document($relation); } diff --git a/tests/e2e/Services/Databases/TablesDB/DatabasesBase.php b/tests/e2e/Services/Databases/TablesDB/DatabasesBase.php index 4d0e9e76a2..2ea0c8c108 100644 --- a/tests/e2e/Services/Databases/TablesDB/DatabasesBase.php +++ b/tests/e2e/Services/Databases/TablesDB/DatabasesBase.php @@ -7680,7 +7680,7 @@ trait DatabasesBase ]); // Create one-to-many relationship - $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $parentTableId . '/columns/relationship', array_merge([ + $relationship = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $parentTableId . '/columns/relationship', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -7690,8 +7690,22 @@ trait DatabasesBase 'twoWay' => false, 'key' => 'children', ]); + $this->assertEquals(202, $relationship['headers']['status-code']); - sleep(1); + // Wait for relationship column to be available + $maxAttempts = 10; + for ($i = 0; $i < $maxAttempts; $i++) { + $columns = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $parentTableId . '/columns', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ])); + $columnKeys = array_column($columns['body']['columns'], 'key'); + if (in_array('children', $columnKeys)) { + break; + } + usleep(200000); + } // ID too long (>36 chars) should fail $response = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $parentTableId . '/rows', array_merge([