99use Illuminate \Database \Eloquent \Model ;
1010use Illuminate \Database \Eloquent \Relations \MorphToMany as EloquentMorphToMany ;
1111use Illuminate \Support \Arr ;
12+ use MongoDB \BSON \ObjectId ;
1213
1314use function array_diff ;
1415use function array_key_exists ;
1718use function array_merge ;
1819use function array_reduce ;
1920use function array_values ;
21+ use function collect ;
2022use function count ;
23+ use function in_array ;
2124use function is_array ;
2225use function is_numeric ;
2326
@@ -74,11 +77,20 @@ public function addEagerConstraints(array $models)
7477 protected function setWhere ()
7578 {
7679 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 });
7882
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+ }
8088 } 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+ };
8294 }
8395
8496 return $ this ;
@@ -128,9 +140,25 @@ public function sync($ids, $detaching = true)
128140 // in this joining table. We'll spin through the given IDs, checking to see
129141 // if they exist in the array of current ones, and if not we will insert.
130142 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+ }
132153 } 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+ }
134162 }
135163
136164 $ records = $ this ->formatRecordsList ($ ids );
@@ -185,15 +213,19 @@ public function attach($id, array $attributes = [], $touch = true)
185213
186214 if ($ this ->getInverse ()) {
187215 // 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+ }
194226
195227 // 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 );
197229 } else {
198230 // Attach the new parent id to the related model.
199231 $ model ->push ($ this ->table , [
@@ -204,7 +236,11 @@ public function attach($id, array $attributes = [], $touch = true)
204236 ], true );
205237
206238 // 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+ }
208244 }
209245 } else {
210246 if ($ id instanceof Collection) {
@@ -221,13 +257,19 @@ public function attach($id, array $attributes = [], $touch = true)
221257 $ query ->push ($ this ->foreignPivotKey , $ this ->parent ->{$ this ->parentKey });
222258
223259 // 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+ }
231273 }
232274 } else {
233275 // Attach the new parent id to the related model.
@@ -239,7 +281,13 @@ public function attach($id, array $attributes = [], $touch = true)
239281 ], true );
240282
241283 // 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+ }
243291 }
244292 }
245293
@@ -276,7 +324,13 @@ public function detach($ids = [], $touch = true)
276324 ];
277325 }
278326
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+ }
280334
281335 // Prepare the query to select all related objects.
282336 if (count ($ ids ) > 0 ) {
@@ -287,7 +341,13 @@ public function detach($ids = [], $touch = true)
287341 $ query ->pull ($ this ->foreignPivotKey , $ this ->parent ->{$ this ->parentKey });
288342 } else {
289343 // 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+ }
291351
292352 // Prepare the query to select all related objects.
293353 if (count ($ ids ) > 0 ) {
@@ -390,4 +450,20 @@ public function extractIds(array $data, ?string $relatedPivotKey = null)
390450 return $ carry ;
391451 }, []);
392452 }
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+ }
393469}
0 commit comments