Skip to content

Commit e7015c0

Browse files
committed
PHPORM-147 Make id an alias for _id
1 parent f654b83 commit e7015c0

File tree

3 files changed

+84
-54
lines changed

3 files changed

+84
-54
lines changed

src/Query/Builder.php

+15-12
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,17 @@ public function insert(array $values)
682682
$values = [$values];
683683
}
684684

685+
// Compatibility with Eloquent queries that uses "id" instead of MongoDB's _id
686+
foreach ($values as &$document) {
687+
if (isset($document['id'])) {
688+
if (isset($document['_id']) && $document['_id'] !== $document['id']) {
689+
throw new InvalidArgumentException('Cannot insert document with different "id" and "_id" values');
690+
}
691+
692+
$document['_id'] = $document['id'];
693+
}
694+
}
695+
685696
$options = $this->inheritConnectionOptions();
686697

687698
$result = $this->collection->insertMany($values, $options);
@@ -752,18 +763,6 @@ public function decrement($column, $amount = 1, array $extra = [], array $option
752763
return $this->increment($column, -1 * $amount, $extra, $options);
753764
}
754765

755-
/** @inheritdoc */
756-
public function chunkById($count, callable $callback, $column = '_id', $alias = null)
757-
{
758-
return parent::chunkById($count, $callback, $column, $alias);
759-
}
760-
761-
/** @inheritdoc */
762-
public function forPageAfterId($perPage = 15, $lastId = 0, $column = '_id')
763-
{
764-
return parent::forPageAfterId($perPage, $lastId, $column);
765-
}
766-
767766
/** @inheritdoc */
768767
public function pluck($column, $key = null)
769768
{
@@ -1039,6 +1038,10 @@ public function where($column, $operator = null, $value = null, $boolean = 'and'
10391038
{
10401039
$params = func_get_args();
10411040

1041+
if ($column === 'id') {
1042+
$params[0] = $column = '_id';
1043+
}
1044+
10421045
// Remove the leading $ from operators.
10431046
if (func_num_args() >= 3) {
10441047
$operator = &$params[1];

tests/Query/BuilderTest.php

+52-42
Original file line numberDiff line numberDiff line change
@@ -135,37 +135,37 @@ public static function provideQueryBuilderToMql(): iterable
135135
'find' => [
136136
[
137137
'$or' => [
138-
['id' => 1],
139-
['id' => ['$in' => [1, 2, 3]]],
138+
['foo' => 1],
139+
['foo' => ['$in' => [1, 2, 3]]],
140140
],
141141
],
142142
[], // options
143143
],
144144
],
145-
fn (Builder $builder) => $builder->where('id', '=', 1)
146-
->orWhereIn('id', [1, 2, 3]),
145+
fn (Builder $builder) => $builder->where('foo', '=', 1)
146+
->orWhereIn('foo', [1, 2, 3]),
147147
];
148148

149149
/** @see DatabaseQueryBuilderTest::testBasicWhereNotIns */
150150
yield 'whereNotIn' => [
151-
['find' => [['id' => ['$nin' => [1, 2, 3]]], []]],
152-
fn (Builder $builder) => $builder->whereNotIn('id', [1, 2, 3]),
151+
['find' => [['foo' => ['$nin' => [1, 2, 3]]], []]],
152+
fn (Builder $builder) => $builder->whereNotIn('foo', [1, 2, 3]),
153153
];
154154

155155
yield 'orWhereNotIn' => [
156156
[
157157
'find' => [
158158
[
159159
'$or' => [
160-
['id' => 1],
161-
['id' => ['$nin' => [1, 2, 3]]],
160+
['foo' => 1],
161+
['foo' => ['$nin' => [1, 2, 3]]],
162162
],
163163
],
164164
[], // options
165165
],
166166
],
167-
fn (Builder $builder) => $builder->where('id', '=', 1)
168-
->orWhereNotIn('id', [1, 2, 3]),
167+
fn (Builder $builder) => $builder->where('foo', '=', 1)
168+
->orWhereNotIn('foo', [1, 2, 3]),
169169
];
170170

171171
/** @see DatabaseQueryBuilderTest::testEmptyWhereIns */
@@ -220,15 +220,15 @@ public static function provideQueryBuilderToMql(): iterable
220220
'find' => [
221221
[
222222
'$or' => [
223-
['id' => 1],
223+
['age' => 1],
224224
['email' => 'foo'],
225225
],
226226
],
227227
[], // options
228228
],
229229
],
230230
fn (Builder $builder) => $builder
231-
->where('id', '=', 1)
231+
->where('age', '=', 1)
232232
->orWhere('email', '=', 'foo'),
233233
];
234234

@@ -589,16 +589,16 @@ function (Builder $builder) {
589589
'find' => [
590590
[
591591
'$or' => [
592-
['id' => 1],
593-
['id' => ['$gte' => 3, '$lte' => 5]],
592+
['age' => 1],
593+
['age' => ['$gte' => 3, '$lte' => 5]],
594594
],
595595
],
596596
[], // options
597597
],
598598
],
599599
fn (Builder $builder) => $builder
600-
->where('id', '=', 1)
601-
->orWhereBetween('id', [3, 5]),
600+
->where('age', '=', 1)
601+
->orWhereBetween('age', [3, 5]),
602602
];
603603

604604
/** @link https://www.mongodb.com/docs/manual/reference/bson-type-comparison-order/#arrays */
@@ -607,48 +607,48 @@ function (Builder $builder) {
607607
'find' => [
608608
[
609609
'$or' => [
610-
['id' => 1],
611-
['id' => ['$gte' => [4], '$lte' => [6, 8]]],
610+
['age' => 1],
611+
['age' => ['$gte' => [4], '$lte' => [6, 8]]],
612612
],
613613
],
614614
[], // options
615615
],
616616
],
617617
fn (Builder $builder) => $builder
618-
->where('id', '=', 1)
619-
->orWhereBetween('id', [[4], [6, 8]]),
618+
->where('age', '=', 1)
619+
->orWhereBetween('age', [[4], [6, 8]]),
620620
];
621621

622622
yield 'orWhereBetween collection' => [
623623
[
624624
'find' => [
625625
[
626626
'$or' => [
627-
['id' => 1],
628-
['id' => ['$gte' => 3, '$lte' => 4]],
627+
['age' => 1],
628+
['age' => ['$gte' => 3, '$lte' => 4]],
629629
],
630630
],
631631
[], // options
632632
],
633633
],
634634
fn (Builder $builder) => $builder
635-
->where('id', '=', 1)
636-
->orWhereBetween('id', collect([3, 4])),
635+
->where('age', '=', 1)
636+
->orWhereBetween('age', collect([3, 4])),
637637
];
638638

639639
yield 'whereNotBetween array of numbers' => [
640640
[
641641
'find' => [
642642
[
643643
'$or' => [
644-
['id' => ['$lte' => 1]],
645-
['id' => ['$gte' => 2]],
644+
['age' => ['$lte' => 1]],
645+
['age' => ['$gte' => 2]],
646646
],
647647
],
648648
[], // options
649649
],
650650
],
651-
fn (Builder $builder) => $builder->whereNotBetween('id', [1, 2]),
651+
fn (Builder $builder) => $builder->whereNotBetween('age', [1, 2]),
652652
];
653653

654654
/** @see DatabaseQueryBuilderTest::testOrWhereNotBetween() */
@@ -657,11 +657,11 @@ function (Builder $builder) {
657657
'find' => [
658658
[
659659
'$or' => [
660-
['id' => 1],
660+
['age' => 1],
661661
[
662662
'$or' => [
663-
['id' => ['$lte' => 3]],
664-
['id' => ['$gte' => 5]],
663+
['age' => ['$lte' => 3]],
664+
['age' => ['$gte' => 5]],
665665
],
666666
],
667667
],
@@ -670,20 +670,20 @@ function (Builder $builder) {
670670
],
671671
],
672672
fn (Builder $builder) => $builder
673-
->where('id', '=', 1)
674-
->orWhereNotBetween('id', [3, 5]),
673+
->where('age', '=', 1)
674+
->orWhereNotBetween('age', [3, 5]),
675675
];
676676

677677
yield 'orWhereNotBetween nested array of numbers' => [
678678
[
679679
'find' => [
680680
[
681681
'$or' => [
682-
['id' => 1],
682+
['age' => 1],
683683
[
684684
'$or' => [
685-
['id' => ['$lte' => [2, 3]]],
686-
['id' => ['$gte' => [5]]],
685+
['age' => ['$lte' => [2, 3]]],
686+
['age' => ['$gte' => [5]]],
687687
],
688688
],
689689
],
@@ -692,20 +692,20 @@ function (Builder $builder) {
692692
],
693693
],
694694
fn (Builder $builder) => $builder
695-
->where('id', '=', 1)
696-
->orWhereNotBetween('id', [[2, 3], [5]]),
695+
->where('age', '=', 1)
696+
->orWhereNotBetween('age', [[2, 3], [5]]),
697697
];
698698

699699
yield 'orWhereNotBetween collection' => [
700700
[
701701
'find' => [
702702
[
703703
'$or' => [
704-
['id' => 1],
704+
['age' => 1],
705705
[
706706
'$or' => [
707-
['id' => ['$lte' => 3]],
708-
['id' => ['$gte' => 4]],
707+
['age' => ['$lte' => 3]],
708+
['age' => ['$gte' => 4]],
709709
],
710710
],
711711
],
@@ -714,8 +714,8 @@ function (Builder $builder) {
714714
],
715715
],
716716
fn (Builder $builder) => $builder
717-
->where('id', '=', 1)
718-
->orWhereNotBetween('id', collect([3, 4])),
717+
->where('age', '=', 1)
718+
->orWhereNotBetween('age', collect([3, 4])),
719719
];
720720

721721
yield 'where like' => [
@@ -1160,6 +1160,16 @@ function (Builder $elemMatchQuery): void {
11601160
),
11611161
];
11621162

1163+
yield 'id alias for _id' => [
1164+
['find' => [['_id' => 1], []]],
1165+
fn (Builder $builder) => $builder->where('id', 1),
1166+
];
1167+
1168+
yield 'id alias for _id with $or' => [
1169+
['find' => [['$or' => [['_id' => 1], ['_id' => 2]]], []]],
1170+
fn (Builder $builder) => $builder->where('id', 1)->orWhere('id', 2),
1171+
];
1172+
11631173
// Method added in Laravel v10.47.0
11641174
if (method_exists(Builder::class, 'whereAll')) {
11651175
/** @see DatabaseQueryBuilderTest::testWhereAll */

tests/QueryBuilderTest.php

+17
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use MongoDB\Laravel\Query\Builder;
2525
use MongoDB\Laravel\Tests\Models\Item;
2626
use MongoDB\Laravel\Tests\Models\User;
27+
use PHPUnit\Framework\Attributes\TestWith;
2728
use Stringable;
2829

2930
use function count;
@@ -964,4 +965,20 @@ public function testStringableColumn()
964965
$user = DB::collection('users')->where($ageColumn, 29)->first();
965966
$this->assertEquals('John Doe', $user['name']);
966967
}
968+
969+
#[TestWith(['id', 'id'])]
970+
#[TestWith(['id', '_id'])]
971+
#[TestWith(['_id', 'id'])]
972+
public function testIdAlias($insertId, $queryId): void
973+
{
974+
DB::collection('items')->insert([$insertId => 'abc', 'name' => 'Karting']);
975+
$item = DB::collection('items')->where($queryId, '=', 'abc')->first();
976+
$this->assertNotNull($item);
977+
$this->assertSame('abc', $item['_id']);
978+
$this->assertSame('Karting', $item['name']);
979+
980+
DB::collection('items')->where($insertId, '=', 'abc')->update(['name' => 'Bike']);
981+
$item = DB::collection('items')->where($queryId, '=', 'abc')->first();
982+
$this->assertSame('Bike', $item['name']);
983+
}
967984
}

0 commit comments

Comments
 (0)