@@ -27,29 +27,39 @@ public function addEagerConstraints(array $models)
2727 $ ids = $ this ->getKeys ($ models , $ this ->table );
2828 $ ids = $ this ->extractIds ($ ids [0 ] ?? []);
2929 $ this ->query ->whereIn ($ this ->relatedKey , $ ids );
30- } else {
31- parent ::addEagerConstraints ($ models );
32- $ this ->query ->where ($ this ->qualifyPivotColumn ($ this ->morphType ), $ this ->morphClass );
30+
31+ return ;
3332 }
33+
34+ // Non-inverse: standard eager constraints with morph type filter
35+ parent ::addEagerConstraints ($ models );
36+ $ this ->query ->where ($ this ->qualifyPivotColumn ($ this ->morphType ), $ this ->morphClass );
3437 }
3538
3639 protected function setWhere ()
3740 {
41+ if ($ this ->getInverse () && $ this ->isElasticParent ()) {
42+ $ ids = $ this ->extractIds ((array ) $ this ->parent ->{$ this ->table });
43+ $ this ->query ->whereIn ($ this ->relatedKey , $ ids );
44+
45+ return $ this ;
46+ }
47+
3848 if ($ this ->getInverse ()) {
39- if ($ this ->isElasticParent ()) {
40- $ ids = $ this ->extractIds ((array ) $ this ->parent ->{$ this ->table });
41- $ this ->query ->whereIn ($ this ->relatedKey , $ ids );
42- } else {
43- $ this ->query ->whereIn ($ this ->foreignPivotKey , (array ) $ this ->parent ->{$ this ->parentKey });
44- }
45- } else {
46- if ($ this ->isElasticParent ()) {
47- $ this ->query ->whereIn ($ this ->relatedKey , (array ) $ this ->parent ->{$ this ->relatedPivotKey });
48- } else {
49- $ this ->query ->whereIn ($ this ->getQualifiedForeignPivotKeyName (), (array ) $ this ->parent ->{$ this ->parentKey });
50- }
49+ $ this ->query ->whereIn ($ this ->foreignPivotKey , (array ) $ this ->parent ->{$ this ->parentKey });
50+
51+ return $ this ;
5152 }
5253
54+ if ($ this ->isElasticParent ()) {
55+ $ this ->query ->whereIn ($ this ->relatedKey , (array ) $ this ->parent ->{$ this ->relatedPivotKey });
56+
57+ return $ this ;
58+ }
59+
60+ // SQL parent, non-inverse
61+ $ this ->query ->whereIn ($ this ->getQualifiedForeignPivotKeyName (), (array ) $ this ->parent ->{$ this ->parentKey });
62+
5363 return $ this ;
5464 }
5565
@@ -153,47 +163,47 @@ public function detach($ids = [], $touch = true)
153163 */
154164 private function attachIdsToParent (array $ ids ): void
155165 {
156- if ($ this ->getInverse ()) {
157- $ morphClass = $ this ->related instanceof Model ? $ this ->related ->getMorphClass () : null ;
158-
159- if ($ this ->isElasticParent ()) {
160- foreach ($ ids as $ id ) {
161- $ this ->parent ->push ($ this ->table , [
162- $ this ->buildMorphEntry ($ this ->relatedPivotKey , $ id , $ morphClass ),
163- ], true );
164- }
165- } else {
166- foreach ($ ids as $ id ) {
167- $ this ->addIdToParentRelationData ($ id );
168- }
169- }
170- } else {
171- if ($ this ->isElasticParent ()) {
172- $ this ->parent ->push ($ this ->relatedPivotKey , $ ids , true );
173- } else {
174- foreach ($ ids as $ id ) {
175- $ this ->addIdToParentRelationData ($ id );
176- }
166+ if (! $ this ->isElasticParent ()) {
167+ foreach ($ ids as $ id ) {
168+ $ this ->addIdToParentRelationData ($ id );
177169 }
170+
171+ return ;
172+ }
173+
174+ if (! $ this ->getInverse ()) {
175+ $ this ->parent ->push ($ this ->relatedPivotKey , $ ids , true );
176+
177+ return ;
178+ }
179+
180+ $ morphClass = $ this ->related instanceof Model ? $ this ->related ->getMorphClass () : null ;
181+ foreach ($ ids as $ id ) {
182+ $ this ->parent ->push ($ this ->table , [
183+ $ this ->buildMorphEntry ($ this ->relatedPivotKey , $ id , $ morphClass ),
184+ ], true );
178185 }
179186 }
180187
181188 /**
182189 * Push parent reference onto a single related model instance.
183190 *
184- * Inverse: related stores flat parent IDs in foreignPivotKey
191+ * Inverse: related stores flat parent IDs in foreignPivotKey
185192 * Non-inverse: related stores morph entries in $this->table
186193 */
187194 private function attachParentToRelatedModel (Model $ model ): void
188195 {
189196 if ($ this ->getInverse ()) {
190197 $ model ->push ($ this ->foreignPivotKey , (array ) $ this ->parent ->{$ this ->parentKey }, true );
191- } else {
192- $ morphClass = $ this ->parent instanceof Model ? $ this ->parent ->getMorphClass () : null ;
193- $ model ->push ($ this ->table , [
194- $ this ->buildMorphEntry ($ this ->foreignPivotKey , $ this ->parent ->{$ this ->parentKey }, $ morphClass ),
195- ], true );
198+
199+ return ;
196200 }
201+
202+ // Non-inverse: store morph entry on related
203+ $ morphClass = $ this ->parent instanceof Model ? $ this ->parent ->getMorphClass () : null ;
204+ $ model ->push ($ this ->table , [
205+ $ this ->buildMorphEntry ($ this ->foreignPivotKey , $ this ->parent ->{$ this ->parentKey }, $ morphClass ),
206+ ], true );
197207 }
198208
199209 /**
@@ -205,12 +215,15 @@ private function attachParentToRelatedQuery($query): void
205215 {
206216 if ($ this ->getInverse ()) {
207217 $ query ->push ($ this ->foreignPivotKey , $ this ->parent ->{$ this ->parentKey });
208- } else {
209- $ morphClass = $ this ->parent instanceof Model ? $ this ->parent ->getMorphClass () : null ;
210- $ query ->push ($ this ->table , [
211- $ this ->buildMorphEntry ($ this ->foreignPivotKey , $ this ->parent ->{$ this ->parentKey }, $ morphClass ),
212- ], true );
218+
219+ return ;
213220 }
221+
222+ // Non-inverse: store morph entry on related
223+ $ morphClass = $ this ->parent instanceof Model ? $ this ->parent ->getMorphClass () : null ;
224+ $ query ->push ($ this ->table , [
225+ $ this ->buildMorphEntry ($ this ->foreignPivotKey , $ this ->parent ->{$ this ->parentKey }, $ morphClass ),
226+ ], true );
214227 }
215228
216229 // ------------------------------------------------------------------
@@ -220,47 +233,51 @@ private function attachParentToRelatedQuery($query): void
220233 /**
221234 * Remove related IDs from the parent model.
222235 *
223- * Inverse: removes morph entries from $this->table
236+ * Inverse: removes morph entries from $this->table
224237 * Non-inverse: removes flat IDs from $this->relatedPivotKey
225238 */
226239 private function detachIdsFromParent (array $ ids ): void
227240 {
228- if ($ this ->getInverse ()) {
229- $ data = array_map (fn ($ item ) => $ this ->buildMorphEntry (
230- $ this ->relatedPivotKey , $ item , $ this ->related ->getMorphClass ()
231- ), $ ids );
232-
233- if ($ this ->isElasticParent ()) {
234- $ this ->parent ->pull ($ this ->table , $ data );
235- } else {
236- $ this ->removeIdsFromParentRelationData ($ this ->extractIds ($ data ));
237- }
238- } else {
239- if ($ this ->isElasticParent ()) {
240- $ this ->parent ->pull ($ this ->relatedPivotKey , $ ids );
241- } else {
242- $ this ->removeIdsFromParentRelationData ($ ids );
243- }
241+ if (! $ this ->getInverse ()) {
242+ $ this ->isElasticParent ()
243+ ? $ this ->parent ->pull ($ this ->relatedPivotKey , $ ids )
244+ : $ this ->removeIdsFromParentRelationData ($ ids );
245+
246+ return ;
244247 }
248+
249+ $ morphEntries = [];
250+ foreach ($ ids as $ id ) {
251+ $ morphEntries [] = $ this ->buildMorphEntry (
252+ $ this ->relatedPivotKey , $ id , $ this ->related ->getMorphClass ()
253+ );
254+ }
255+
256+ $ this ->isElasticParent ()
257+ ? $ this ->parent ->pull ($ this ->table , $ morphEntries )
258+ : $ this ->removeIdsFromParentRelationData ($ this ->extractIds ($ morphEntries ));
245259 }
246260
247261 /**
248262 * Remove parent reference from the related models.
249263 *
250- * Inverse: removes flat parent ID from foreignPivotKey
264+ * Inverse: removes flat parent ID from foreignPivotKey
251265 * Non-inverse: removes morph entry from $this->table
252266 */
253267 private function detachParentFromRelated ($ query ): void
254268 {
255269 if ($ this ->getInverse ()) {
256270 $ query ->pull ($ this ->foreignPivotKey , $ this ->parent ->{$ this ->parentKey });
257- } else {
258- $ query ->pull ($ this ->table , [
259- $ this ->buildMorphEntry (
260- $ this ->foreignPivotKey , $ this ->parent ->{$ this ->parentKey }, $ this ->parent ->getMorphClass ()
261- ),
262- ]);
271+
272+ return ;
263273 }
274+
275+ // Non-inverse: remove morph entry from related
276+ $ query ->pull ($ this ->table , [
277+ $ this ->buildMorphEntry (
278+ $ this ->foreignPivotKey , $ this ->parent ->{$ this ->parentKey }, $ this ->parent ->getMorphClass ()
279+ ),
280+ ]);
264281 }
265282
266283 // ------------------------------------------------------------------
@@ -291,15 +308,12 @@ protected function buildDictionary(Collection $results)
291308 $ dictionary = [];
292309
293310 foreach ($ results as $ result ) {
294- if ($ this ->getInverse ()) {
295- foreach ($ result ->$ foreign as $ item ) {
296- $ dictionary [$ item ][] = $ result ;
297- }
298- } else {
299- $ items = $ this ->extractIds ($ result ->{$ this ->table } ?? [], $ foreign );
300- foreach ($ items as $ item ) {
301- $ dictionary [$ item ][] = $ result ;
302- }
311+ $ items = $ this ->getInverse ()
312+ ? $ result ->$ foreign
313+ : $ this ->extractIds ($ result ->{$ this ->table } ?? [], $ foreign );
314+
315+ foreach ($ items as $ item ) {
316+ $ dictionary [$ item ][] = $ result ;
303317 }
304318 }
305319
@@ -308,14 +322,15 @@ protected function buildDictionary(Collection $results)
308322
309323 public function extractIds (array $ data , ?string $ relatedPivotKey = null )
310324 {
311- $ relatedPivotKey = $ relatedPivotKey ?: $ this ->relatedPivotKey ;
325+ $ key = $ relatedPivotKey ?: $ this ->relatedPivotKey ;
326+ $ ids = [];
312327
313- return array_reduce ($ data, function ( $ carry , $ item) use ( $ relatedPivotKey ) {
314- if (is_array ($ item ) && array_key_exists ($ relatedPivotKey , $ item )) {
315- $ carry [] = $ item [$ relatedPivotKey ];
328+ foreach ($ data as $ item ) {
329+ if (is_array ($ item ) && array_key_exists ($ key , $ item )) {
330+ $ ids [] = $ item [$ key ];
316331 }
332+ }
317333
318- return $ carry ;
319- }, []);
334+ return $ ids ;
320335 }
321336}
0 commit comments