Skip to content

Commit 68e57f4

Browse files
committed
Fix aliasing _id in embedded documents + add test
1 parent 48c14cc commit 68e57f4

File tree

2 files changed

+91
-1
lines changed

2 files changed

+91
-1
lines changed

Diff for: src/Eloquent/Builder.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use MongoDB\Model\BSONDocument;
1919

2020
use function array_key_exists;
21+
use function array_map;
2122
use function array_replace;
2223
use function collect;
2324
use function is_array;
@@ -237,7 +238,7 @@ public function raw($value = null)
237238
// Convert MongoCursor results to a collection of models.
238239
if ($results instanceof CursorInterface) {
239240
$results->setTypeMap(['root' => 'array', 'document' => 'array', 'array' => 'array']);
240-
$results = $this->query->aliasIdForResult(iterator_to_array($results));
241+
$results = array_map(fn ($document) => $this->query->aliasIdForResult($document), iterator_to_array($results));
241242

242243
return $this->model->hydrate($results);
243244
}

Diff for: tests/QueryBuilderTest.php

+89
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@
2020
use MongoDB\BSON\UTCDateTime;
2121
use MongoDB\Collection;
2222
use MongoDB\Driver\Cursor;
23+
use MongoDB\Driver\CursorInterface;
2324
use MongoDB\Driver\Monitoring\CommandFailedEvent;
2425
use MongoDB\Driver\Monitoring\CommandStartedEvent;
2526
use MongoDB\Driver\Monitoring\CommandSubscriber;
2627
use MongoDB\Driver\Monitoring\CommandSucceededEvent;
28+
use MongoDB\Laravel\Connection;
2729
use MongoDB\Laravel\Query\Builder;
2830
use MongoDB\Laravel\Tests\Models\Item;
2931
use MongoDB\Laravel\Tests\Models\User;
@@ -336,6 +338,93 @@ public function testRaw()
336338
$this->assertEquals('Jane Doe', $results[0]->name);
337339
}
338340

341+
public function testRawResultRenameId()
342+
{
343+
$connection = DB::connection('mongodb');
344+
self::assertInstanceOf(Connection::class, $connection);
345+
346+
$date = Carbon::createFromDate(1986, 12, 31)->setTime(12, 0, 0);
347+
User::insert([
348+
['id' => 1, 'name' => 'Jane Doe', 'address' => ['id' => 11, 'city' => 'Ghent'], 'birthday' => $date],
349+
['id' => 2, 'name' => 'John Doe', 'address' => ['id' => 12, 'city' => 'Brussels'], 'birthday' => $date],
350+
]);
351+
352+
// Using raw database query, result is not altered
353+
$results = $connection->table('users')->raw(fn (Collection $collection) => $collection->find([]));
354+
self::assertInstanceOf(CursorInterface::class, $results);
355+
$results = $results->toArray();
356+
self::assertCount(2, $results);
357+
358+
self::assertObjectHasProperty('_id', $results[0]);
359+
self::assertObjectNotHasProperty('id', $results[0]);
360+
self::assertSame(1, $results[0]->_id);
361+
362+
self::assertObjectHasProperty('_id', $results[0]->address);
363+
self::assertObjectNotHasProperty('id', $results[0]->address);
364+
self::assertSame(11, $results[0]->address->_id);
365+
366+
self::assertInstanceOf(UTCDateTime::class, $results[0]->birthday);
367+
368+
// Using Eloquent query, result is transformed
369+
self::assertTrue($connection->getRenameEmbeddedIdField());
370+
$results = User::raw(fn (Collection $collection) => $collection->find([]));
371+
self::assertInstanceOf(LaravelCollection::class, $results);
372+
self::assertCount(2, $results);
373+
374+
$attributes = $results->first()->getAttributes();
375+
self::assertArrayHasKey('id', $attributes);
376+
self::assertArrayNotHasKey('_id', $attributes);
377+
self::assertSame(1, $attributes['id']);
378+
379+
self::assertArrayHasKey('id', $attributes['address']);
380+
self::assertArrayNotHasKey('_id', $attributes['address']);
381+
self::assertSame(11, $attributes['address']['id']);
382+
383+
self::assertEquals($date, $attributes['birthday']);
384+
385+
// Single result
386+
$result = User::raw(fn (Collection $collection) => $collection->findOne([], ['typeMap' => ['root' => 'object', 'document' => 'array']]));
387+
self::assertInstanceOf(User::class, $result);
388+
389+
$attributes = $result->getAttributes();
390+
self::assertArrayHasKey('id', $attributes);
391+
self::assertArrayNotHasKey('_id', $attributes);
392+
self::assertSame(1, $attributes['id']);
393+
394+
self::assertArrayHasKey('id', $attributes['address']);
395+
self::assertArrayNotHasKey('_id', $attributes['address']);
396+
self::assertSame(11, $attributes['address']['id']);
397+
398+
// Change the renameEmbeddedIdField option
399+
$connection->setRenameEmbeddedIdField(false);
400+
401+
$results = User::raw(fn (Collection $collection) => $collection->find([]));
402+
self::assertInstanceOf(LaravelCollection::class, $results);
403+
self::assertCount(2, $results);
404+
405+
$attributes = $results->first()->getAttributes();
406+
self::assertArrayHasKey('id', $attributes);
407+
self::assertArrayNotHasKey('_id', $attributes);
408+
self::assertSame(1, $attributes['id']);
409+
410+
self::assertArrayHasKey('_id', $attributes['address']);
411+
self::assertArrayNotHasKey('id', $attributes['address']);
412+
self::assertSame(11, $attributes['address']['_id']);
413+
414+
// Single result
415+
$result = User::raw(fn (Collection $collection) => $collection->findOne([]));
416+
self::assertInstanceOf(User::class, $result);
417+
418+
$attributes = $result->getAttributes();
419+
self::assertArrayHasKey('id', $attributes);
420+
self::assertArrayNotHasKey('_id', $attributes);
421+
self::assertSame(1, $attributes['id']);
422+
423+
self::assertArrayHasKey('_id', $attributes['address']);
424+
self::assertArrayNotHasKey('id', $attributes['address']);
425+
self::assertSame(11, $attributes['address']['_id']);
426+
}
427+
339428
public function testPush()
340429
{
341430
$id = DB::table('users')->insertGetId([

0 commit comments

Comments
 (0)