diff --git a/src/Eloquent/Model.php b/src/Eloquent/Model.php index f7b4f1f36..b9f87e1ad 100644 --- a/src/Eloquent/Model.php +++ b/src/Eloquent/Model.php @@ -319,6 +319,34 @@ protected function fromDecimal($value, $decimals) return new Decimal128($this->asDecimal($value, $decimals)); } + /** + * Convert MongoDB objects to their string representations. + * + * This method converts MongoDB related objects (ObjectID, Binary, UTCDateTime) + * to their serialized representations, ensuring the values can be correctly + * serialized when the model is converted to JSON. + * + * @param mixed $value The value to convert + * + * @return mixed + */ + protected function convertMongoObjects(mixed $value): mixed + { + if ($value instanceof ObjectID) { + $value = (string) $value; + } elseif ($value instanceof Binary) { + $value = (string) $value->getData(); + } elseif ($value instanceof UTCDateTime) { + $value = $this->serializeDate($value->toDateTime()); + } elseif (is_array($value)) { + foreach ($value as &$nestedValue) { + $nestedValue = $this->convertMongoObjects($nestedValue); + } + } + + return $value; + } + /** @inheritdoc */ public function attributesToArray() { @@ -329,11 +357,7 @@ public function attributesToArray() // of mimics the SQL behaviour so that dates are formatted // nicely when your models are converted to JSON. foreach ($attributes as $key => &$value) { - if ($value instanceof ObjectID) { - $value = (string) $value; - } elseif ($value instanceof Binary) { - $value = (string) $value->getData(); - } + $value = $this->convertMongoObjects($value); } return $attributes; diff --git a/tests/EmbeddedRelationsTest.php b/tests/EmbeddedRelationsTest.php index 2dd558679..d4d54bd48 100644 --- a/tests/EmbeddedRelationsTest.php +++ b/tests/EmbeddedRelationsTest.php @@ -33,6 +33,7 @@ public function tearDown(): void Client::truncate(); Group::truncate(); Photo::truncate(); + Address::truncate(); } public function testEmbedsManySave() @@ -945,4 +946,16 @@ public function testGetQueueableRelationsEmbedsOne() $this->assertEquals(['father'], $user->getQueueableRelations()); $this->assertEquals([], $user->father->getQueueableRelations()); } + + public function testEmbedManySerialization() + { + $address = new Address(['country' => 'France']); + $address->save(); + + $address->addresses()->create(['city' => 'Paris']); + $address->addresses()->create(['city' => 'Nice']); + + $results = $address->toArray(); + $this->assertIsString($results['addresses'][0]['_id']); + } }