9
9
use Illuminate \Database \Eloquent \Model ;
10
10
use Illuminate \Database \Eloquent \Relations \MorphToMany as EloquentMorphToMany ;
11
11
use Illuminate \Support \Arr ;
12
+ use MongoDB \BSON \ObjectId ;
12
13
13
14
use function array_diff ;
14
15
use function array_key_exists ;
17
18
use function array_merge ;
18
19
use function array_reduce ;
19
20
use function array_values ;
21
+ use function collect ;
20
22
use function count ;
23
+ use function in_array ;
21
24
use function is_array ;
22
25
use function is_numeric ;
23
26
@@ -74,11 +77,20 @@ public function addEagerConstraints(array $models)
74
77
protected function setWhere ()
75
78
{
76
79
if ($ this ->getInverse ()) {
77
- $ ids = $ this ->extractIds ((array ) $ this ->parent ->{$ this ->table });
80
+ if ($ this ->parent instanceof \MongoDB \Laravel \Eloquent \Model) {
81
+ $ ids = $ this ->extractIds ((array ) $ this ->parent ->{$ this ->table });
78
82
79
- $ this ->query ->whereIn ($ this ->relatedKey , $ ids );
83
+ $ this ->query ->whereIn ($ this ->relatedKey , $ ids );
84
+ } else {
85
+ $ this ->query
86
+ ->whereIn ($ this ->foreignPivotKey , (array ) $ this ->parent ->{$ this ->parentKey });
87
+ }
80
88
} else {
81
- $ this ->query ->whereIn ($ this ->relatedKey , (array ) $ this ->parent ->{$ this ->relatedPivotKey });
89
+ match ($ this ->parent instanceof \MongoDB \Laravel \Eloquent \Model) {
90
+ true => $ this ->query ->whereIn ($ this ->relatedKey , (array ) $ this ->parent ->{$ this ->relatedPivotKey }),
91
+ false => $ this ->query
92
+ ->whereIn ($ this ->getQualifiedForeignPivotKeyName (), (array ) $ this ->parent ->{$ this ->parentKey }),
93
+ };
82
94
}
83
95
84
96
return $ this ;
@@ -128,9 +140,25 @@ public function sync($ids, $detaching = true)
128
140
// in this joining table. We'll spin through the given IDs, checking to see
129
141
// if they exist in the array of current ones, and if not we will insert.
130
142
if ($ this ->getInverse ()) {
131
- $ current = $ this ->extractIds ($ this ->parent ->{$ this ->table } ?: []);
143
+ $ current = match ($ this ->parent instanceof \MongoDB \Laravel \Eloquent \Model) {
144
+ true => $ this ->parent ->{$ this ->table } ?: [],
145
+ false => $ this ->parent ->{$ this ->relationName } ?: [],
146
+ };
147
+
148
+ if ($ current instanceof Collection) {
149
+ $ current = collect ($ this ->parseIds ($ current ))->flatten ()->toArray ();
150
+ } else {
151
+ $ current = $ this ->extractIds ($ current );
152
+ }
132
153
} else {
133
- $ current = $ this ->parent ->{$ this ->relatedPivotKey } ?: [];
154
+ $ current = match ($ this ->parent instanceof \MongoDB \Laravel \Eloquent \Model) {
155
+ true => $ this ->parent ->{$ this ->relatedPivotKey } ?: [],
156
+ false => $ this ->parent ->{$ this ->relationName } ?: [],
157
+ };
158
+
159
+ if ($ current instanceof Collection) {
160
+ $ current = $ this ->parseIds ($ current );
161
+ }
134
162
}
135
163
136
164
$ records = $ this ->formatRecordsList ($ ids );
@@ -185,15 +213,19 @@ public function attach($id, array $attributes = [], $touch = true)
185
213
186
214
if ($ this ->getInverse ()) {
187
215
// Attach the new ids to the parent model.
188
- $ this ->parent ->push ($ this ->table , [
189
- [
190
- $ this ->relatedPivotKey => $ model ->{$ this ->relatedKey },
191
- $ this ->morphType => $ model ->getMorphClass (),
192
- ],
193
- ], true );
216
+ if ($ this ->parent instanceof \MongoDB \Laravel \Eloquent \Model) {
217
+ $ this ->parent ->push ($ this ->table , [
218
+ [
219
+ $ this ->relatedPivotKey => $ model ->{$ this ->relatedKey },
220
+ $ this ->morphType => $ model ->getMorphClass (),
221
+ ],
222
+ ], true );
223
+ } else {
224
+ $ this ->addIdToParentRelationData ($ id );
225
+ }
194
226
195
227
// Attach the new parent id to the related model.
196
- $ model ->push ($ this ->foreignPivotKey , $ this ->parseIds ( $ this ->parent ) , true );
228
+ $ model ->push ($ this ->foreignPivotKey , ( array ) $ this ->parent ->{ $ this ->parentKey } , true );
197
229
} else {
198
230
// Attach the new parent id to the related model.
199
231
$ model ->push ($ this ->table , [
@@ -204,7 +236,11 @@ public function attach($id, array $attributes = [], $touch = true)
204
236
], true );
205
237
206
238
// Attach the new ids to the parent model.
207
- $ this ->parent ->push ($ this ->relatedPivotKey , (array ) $ id , true );
239
+ if ($ this ->parent instanceof \MongoDB \Laravel \Eloquent \Model) {
240
+ $ this ->parent ->push ($ this ->relatedPivotKey , (array ) $ id , true );
241
+ } else {
242
+ $ this ->addIdToParentRelationData ($ id );
243
+ }
208
244
}
209
245
} else {
210
246
if ($ id instanceof Collection) {
@@ -221,13 +257,19 @@ public function attach($id, array $attributes = [], $touch = true)
221
257
$ query ->push ($ this ->foreignPivotKey , $ this ->parent ->{$ this ->parentKey });
222
258
223
259
// Attach the new ids to the parent model.
224
- foreach ($ id as $ item ) {
225
- $ this ->parent ->push ($ this ->table , [
226
- [
227
- $ this ->relatedPivotKey => $ item ,
228
- $ this ->morphType => $ this ->related instanceof Model ? $ this ->related ->getMorphClass () : null ,
229
- ],
230
- ], true );
260
+ if ($ this ->parent instanceof \MongoDB \Laravel \Eloquent \Model) {
261
+ foreach ($ id as $ item ) {
262
+ $ this ->parent ->push ($ this ->table , [
263
+ [
264
+ $ this ->relatedPivotKey => $ item ,
265
+ $ this ->morphType => $ this ->related instanceof Model ? $ this ->related ->getMorphClass () : null ,
266
+ ],
267
+ ], true );
268
+ }
269
+ } else {
270
+ foreach ($ id as $ item ) {
271
+ $ this ->addIdToParentRelationData ($ item );
272
+ }
231
273
}
232
274
} else {
233
275
// Attach the new parent id to the related model.
@@ -239,7 +281,13 @@ public function attach($id, array $attributes = [], $touch = true)
239
281
], true );
240
282
241
283
// Attach the new ids to the parent model.
242
- $ this ->parent ->push ($ this ->relatedPivotKey , $ id , true );
284
+ if ($ this ->parent instanceof \MongoDB \Laravel \Eloquent \Model) {
285
+ $ this ->parent ->push ($ this ->relatedPivotKey , $ id , true );
286
+ } else {
287
+ foreach ($ id as $ item ) {
288
+ $ this ->addIdToParentRelationData ($ item );
289
+ }
290
+ }
243
291
}
244
292
}
245
293
@@ -276,7 +324,13 @@ public function detach($ids = [], $touch = true)
276
324
];
277
325
}
278
326
279
- $ this ->parent ->pull ($ this ->table , $ data );
327
+ if ($ this ->parent instanceof \MongoDB \Laravel \Eloquent \Model) {
328
+ $ this ->parent ->pull ($ this ->table , $ data );
329
+ } else {
330
+ $ value = $ this ->parent ->{$ this ->relationName }
331
+ ->filter (fn ($ rel ) => ! in_array ($ rel ->{$ this ->relatedKey }, $ this ->extractIds ($ data )));
332
+ $ this ->parent ->setRelation ($ this ->relationName , $ value );
333
+ }
280
334
281
335
// Prepare the query to select all related objects.
282
336
if (count ($ ids ) > 0 ) {
@@ -287,7 +341,13 @@ public function detach($ids = [], $touch = true)
287
341
$ query ->pull ($ this ->foreignPivotKey , $ this ->parent ->{$ this ->parentKey });
288
342
} else {
289
343
// Remove the relation from the parent.
290
- $ this ->parent ->pull ($ this ->relatedPivotKey , $ ids );
344
+ if ($ this ->parent instanceof \MongoDB \Laravel \Eloquent \Model) {
345
+ $ this ->parent ->pull ($ this ->relatedPivotKey , $ ids );
346
+ } else {
347
+ $ value = $ this ->parent ->{$ this ->relationName }
348
+ ->filter (fn ($ rel ) => ! in_array ($ rel ->{$ this ->relatedKey }, $ ids ));
349
+ $ this ->parent ->setRelation ($ this ->relationName , $ value );
350
+ }
291
351
292
352
// Prepare the query to select all related objects.
293
353
if (count ($ ids ) > 0 ) {
@@ -390,4 +450,20 @@ public function extractIds(array $data, ?string $relatedPivotKey = null)
390
450
return $ carry ;
391
451
}, []);
392
452
}
453
+
454
+ /**
455
+ * Add the given id to the relation's data of the current parent instance.
456
+ * It helps to keep up-to-date the sql model instances in hybrid relationships.
457
+ *
458
+ * @param ObjectId|string|int $id
459
+ *
460
+ * @return void
461
+ */
462
+ private function addIdToParentRelationData ($ id )
463
+ {
464
+ $ instance = new $ this ->related ();
465
+ $ instance ->forceFill ([$ this ->relatedKey => $ id ]);
466
+ $ relationData = $ this ->parent ->{$ this ->relationName }->push ($ instance )->unique ($ this ->relatedKey );
467
+ $ this ->parent ->setRelation ($ this ->relationName , $ relationData );
468
+ }
393
469
}
0 commit comments