fix: generate unique ID before validation per coderabbit suggestion

This commit is contained in:
Prem Palanisamy
2026-01-26 15:45:42 +00:00
parent cb32dc40ec
commit 1ee2539ce0
5 changed files with 49 additions and 6 deletions
@@ -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));
}
@@ -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);
}
@@ -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);
}
@@ -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);
}
@@ -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([