Skip to content

Commit 3aa2adc

Browse files
authored
fix various problems with belongs to many (#18380)
1 parent bb47918 commit 3aa2adc

File tree

5 files changed

+71
-57
lines changed

5 files changed

+71
-57
lines changed

src/Illuminate/Database/Eloquent/Concerns/HasRelationships.php

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -284,15 +284,15 @@ public function morphMany($related, $name, $type = null, $id = null, $localKey =
284284
*
285285
* @param string $related
286286
* @param string $table
287-
* @param string $foreignKey
288-
* @param string $relatedKey
287+
* @param string $foreignPivotKey
288+
* @param string $relatedPivotKey
289289
* @param string $parentKey
290-
* @param string $localKey
290+
* @param string $relatedKey
291291
* @param string $relation
292292
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
293293
*/
294-
public function belongsToMany($related, $table = null, $foreignKey = null, $relatedKey = null,
295-
$parentKey = null, $localKey = null, $relation = null)
294+
public function belongsToMany($related, $table = null, $foreignPivotKey = null, $relatedPivotKey = null,
295+
$parentKey = null, $relatedKey = null, $relation = null)
296296
{
297297
// If no relationship name was passed, we will pull backtraces to get the
298298
// name of the calling function. We will use that function name as the
@@ -306,9 +306,9 @@ public function belongsToMany($related, $table = null, $foreignKey = null, $rela
306306
// instances as well as the relationship instances we need for this.
307307
$instance = $this->newRelatedInstance($related);
308308

309-
$foreignKey = $foreignKey ?: $this->getForeignKey();
309+
$foreignPivotKey = $foreignPivotKey ?: $this->getForeignKey();
310310

311-
$relatedKey = $relatedKey ?: $instance->getForeignKey();
311+
$relatedPivotKey = $relatedPivotKey ?: $instance->getForeignKey();
312312

313313
// If no table name was provided, we can guess it by concatenating the two
314314
// models using underscores in alphabetical order. The two model names
@@ -318,9 +318,9 @@ public function belongsToMany($related, $table = null, $foreignKey = null, $rela
318318
}
319319

320320
return new BelongsToMany(
321-
$instance->newQuery(), $this, $table, $foreignKey,
322-
$relatedKey, $parentKey ?: $this->getKeyName(),
323-
$localKey ?: $instance->getKeyName(), $relation
321+
$instance->newQuery(), $this, $table, $foreignPivotKey,
322+
$relatedPivotKey, $parentKey ?: $this->getKeyName(),
323+
$relatedKey ?: $instance->getKeyName(), $relation
324324
);
325325
}
326326

@@ -330,12 +330,16 @@ public function belongsToMany($related, $table = null, $foreignKey = null, $rela
330330
* @param string $related
331331
* @param string $name
332332
* @param string $table
333-
* @param string $foreignKey
333+
* @param string $foreignPivotKey
334+
* @param string $relatedPivotKey
335+
* @param string $parentKey
334336
* @param string $relatedKey
335337
* @param bool $inverse
336338
* @return \Illuminate\Database\Eloquent\Relations\MorphToMany
337339
*/
338-
public function morphToMany($related, $name, $table = null, $foreignKey = null, $relatedKey = null, $inverse = false)
340+
public function morphToMany($related, $name, $table = null, $foreignPivotKey = null,
341+
$relatedPivotKey = null, $parentKey = null,
342+
$relatedKey = null, $inverse = false)
339343
{
340344
$caller = $this->guessBelongsToManyRelation();
341345

@@ -344,9 +348,9 @@ public function morphToMany($related, $name, $table = null, $foreignKey = null,
344348
// instances, as well as the relationship instances we need for these.
345349
$instance = $this->newRelatedInstance($related);
346350

347-
$foreignKey = $foreignKey ?: $name.'_id';
351+
$foreignPivotKey = $foreignPivotKey ?: $name.'_id';
348352

349-
$relatedKey = $relatedKey ?: $instance->getForeignKey();
353+
$relatedPivotKey = $relatedPivotKey ?: $instance->getForeignKey();
350354

351355
// Now we're ready to create a new query builder for this related model and
352356
// the relationship instances for this relation. This relations will set
@@ -355,7 +359,8 @@ public function morphToMany($related, $name, $table = null, $foreignKey = null,
355359

356360
return new MorphToMany(
357361
$instance->newQuery(), $this, $name, $table,
358-
$foreignKey, $relatedKey, $caller, $inverse
362+
$foreignPivotKey, $relatedPivotKey, $parentKey ?: $this->getKeyName(),
363+
$relatedKey ?: $instance->getKeyName(), $caller, $inverse
359364
);
360365
}
361366

@@ -365,20 +370,26 @@ public function morphToMany($related, $name, $table = null, $foreignKey = null,
365370
* @param string $related
366371
* @param string $name
367372
* @param string $table
368-
* @param string $foreignKey
373+
* @param string $foreignPivotKey
374+
* @param string $relatedPivotKey
375+
* @param string $parentKey
369376
* @param string $relatedKey
370377
* @return \Illuminate\Database\Eloquent\Relations\MorphToMany
371378
*/
372-
public function morphedByMany($related, $name, $table = null, $foreignKey = null, $relatedKey = null)
379+
public function morphedByMany($related, $name, $table = null, $foreignPivotKey = null,
380+
$relatedPivotKey = null, $parentKey = null, $relatedKey = null)
373381
{
374-
$foreignKey = $foreignKey ?: $this->getForeignKey();
382+
$foreignPivotKey = $foreignPivotKey ?: $this->getForeignKey();
375383

376384
// For the inverse of the polymorphic many-to-many relations, we will change
377385
// the way we determine the foreign and other keys, as it is the opposite
378386
// of the morph-to-many method since we're figuring out these inverses.
379-
$relatedKey = $relatedKey ?: $name.'_id';
387+
$relatedPivotKey = $relatedPivotKey ?: $name.'_id';
380388

381-
return $this->morphToMany($related, $name, $table, $foreignKey, $relatedKey, true);
389+
return $this->morphToMany(
390+
$related, $name, $table, $foreignPivotKey,
391+
$relatedPivotKey, $parentKey, $relatedKey, true
392+
);
382393
}
383394

384395
/**

src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ class BelongsToMany extends Relation
2525
*
2626
* @var string
2727
*/
28-
protected $foreignKey;
28+
protected $foreignPivotKey;
2929

3030
/**
3131
* The associated key of the relation.
3232
*
3333
* @var string
3434
*/
35-
protected $relatedKey;
35+
protected $relatedPivotKey;
3636

3737
/**
3838
* The key name of the parent model.
@@ -46,7 +46,7 @@ class BelongsToMany extends Relation
4646
*
4747
* @var string
4848
*/
49-
protected $localKey;
49+
protected $relatedKey;
5050

5151
/**
5252
* The "name" of the relationship.
@@ -117,15 +117,15 @@ class BelongsToMany extends Relation
117117
* @param string $relationName
118118
* @return void
119119
*/
120-
public function __construct(Builder $query, Model $parent, $table, $foreignKey,
121-
$relatedKey, $parentKey, $localKey, $relationName = null)
120+
public function __construct(Builder $query, Model $parent, $table, $foreignPivotKey,
121+
$relatedPivotKey, $parentKey, $relatedKey, $relationName = null)
122122
{
123123
$this->table = $table;
124-
$this->localKey = $localKey;
125124
$this->parentKey = $parentKey;
126125
$this->relatedKey = $relatedKey;
127-
$this->foreignKey = $foreignKey;
128126
$this->relationName = $relationName;
127+
$this->relatedPivotKey = $relatedPivotKey;
128+
$this->foreignPivotKey = $foreignPivotKey;
129129

130130
parent::__construct($query, $parent);
131131
}
@@ -159,9 +159,9 @@ protected function performJoin($query = null)
159159
// model instance. Then we can set the "where" for the parent models.
160160
$baseTable = $this->related->getTable();
161161

162-
$key = $baseTable.'.'.$this->localKey;
162+
$key = $baseTable.'.'.$this->relatedKey;
163163

164-
$query->join($this->table, $key, '=', $this->getQualifiedRelatedKeyName());
164+
$query->join($this->table, $key, '=', $this->getQualifiedRelatedPivotKeyName());
165165

166166
return $this;
167167
}
@@ -174,7 +174,7 @@ protected function performJoin($query = null)
174174
protected function addWhereConstraints()
175175
{
176176
$this->query->where(
177-
$this->getQualifiedForeignKeyName(), '=', $this->parent->{$this->parentKey}
177+
$this->getQualifiedForeignPivotKeyName(), '=', $this->parent->{$this->parentKey}
178178
);
179179

180180
return $this;
@@ -188,7 +188,7 @@ protected function addWhereConstraints()
188188
*/
189189
public function addEagerConstraints(array $models)
190190
{
191-
$this->query->whereIn($this->getQualifiedForeignKeyName(), $this->getKeys($models));
191+
$this->query->whereIn($this->getQualifiedForeignPivotKeyName(), $this->getKeys($models));
192192
}
193193

194194
/**
@@ -247,7 +247,7 @@ protected function buildDictionary(Collection $results)
247247
$dictionary = [];
248248

249249
foreach ($results as $result) {
250-
$dictionary[$result->pivot->{$this->foreignKey}][] = $result;
250+
$dictionary[$result->pivot->{$this->foreignPivotKey}][] = $result;
251251
}
252252

253253
return $dictionary;
@@ -540,7 +540,7 @@ protected function shouldSelect(array $columns = ['*'])
540540
*/
541541
protected function aliasedPivotColumns()
542542
{
543-
$defaults = [$this->foreignKey, $this->relatedKey];
543+
$defaults = [$this->foreignPivotKey, $this->relatedPivotKey];
544544

545545
return collect(array_merge($defaults, $this->pivotColumns))->map(function ($column) {
546546
return $this->table.'.'.$column.' as pivot_'.$column;
@@ -840,7 +840,7 @@ public function getRelationExistenceQueryForSelfJoin(Builder $query, Builder $pa
840840
*/
841841
public function getExistenceCompareKey()
842842
{
843-
return $this->getQualifiedForeignKeyName();
843+
return $this->getQualifiedForeignPivotKeyName();
844844
}
845845

846846
/**
@@ -893,19 +893,19 @@ public function updatedAt()
893893
*
894894
* @return string
895895
*/
896-
public function getQualifiedForeignKeyName()
896+
public function getQualifiedForeignPivotKeyName()
897897
{
898-
return $this->table.'.'.$this->foreignKey;
898+
return $this->table.'.'.$this->foreignPivotKey;
899899
}
900900

901901
/**
902902
* Get the fully qualified "related key" for the relation.
903903
*
904904
* @return string
905905
*/
906-
public function getQualifiedRelatedKeyName()
906+
public function getQualifiedRelatedPivotKeyName()
907907
{
908-
return $this->table.'.'.$this->relatedKey;
908+
return $this->table.'.'.$this->relatedPivotKey;
909909
}
910910

911911
/**

src/Illuminate/Database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public function toggle($ids, $touch = true)
2929
// checking which of the given ID/records is in the list of current records
3030
// and removing all of those rows from this "intermediate" joining table.
3131
$detach = array_values(array_intersect(
32-
$this->newPivotQuery()->pluck($this->relatedKey)->all(),
32+
$this->newPivotQuery()->pluck($this->relatedPivotKey)->all(),
3333
array_keys($records)
3434
));
3535

@@ -89,7 +89,7 @@ public function sync($ids, $detaching = true)
8989
// in this joining table. We'll spin through the given IDs, checking to see
9090
// if they exist in the array of current ones, and if not we will insert.
9191
$current = $this->newPivotQuery()->pluck(
92-
$this->relatedKey
92+
$this->relatedPivotKey
9393
)->all();
9494

9595
$detach = array_diff($current, array_keys(
@@ -287,9 +287,9 @@ protected function extractAttachIdAndAttributes($key, $value, array $attributes)
287287
*/
288288
protected function baseAttachRecord($id, $timed)
289289
{
290-
$record[$this->relatedKey] = $id;
290+
$record[$this->relatedPivotKey] = $id;
291291

292-
$record[$this->foreignKey] = $this->parent->getKey();
292+
$record[$this->foreignPivotKey] = $this->parent->getKey();
293293

294294
// If the record needs to have creation and update timestamps, we will make
295295
// them by calling the parent model's "freshTimestamp" method which will
@@ -353,7 +353,7 @@ public function detach($ids = null, $touch = true)
353353
return 0;
354354
}
355355

356-
$query->whereIn($this->relatedKey, (array) $ids);
356+
$query->whereIn($this->relatedPivotKey, (array) $ids);
357357
}
358358

359359
// Once we have all of the conditions set on the statement, we are ready
@@ -381,7 +381,7 @@ public function newPivot(array $attributes = [], $exists = false)
381381
$this->parent, $attributes, $this->table, $exists, $this->using
382382
);
383383

384-
return $pivot->setPivotKeys($this->foreignKey, $this->relatedKey);
384+
return $pivot->setPivotKeys($this->foreignPivotKey, $this->relatedPivotKey);
385385
}
386386

387387
/**
@@ -413,7 +413,7 @@ public function newPivotStatement()
413413
*/
414414
public function newPivotStatementForId($id)
415415
{
416-
return $this->newPivotQuery()->where($this->relatedKey, $id);
416+
return $this->newPivotQuery()->where($this->relatedPivotKey, $id);
417417
}
418418

419419
/**
@@ -433,7 +433,7 @@ protected function newPivotQuery()
433433
call_user_func_array([$query, 'whereIn'], $arguments);
434434
}
435435

436-
return $query->where($this->foreignKey, $this->parent->getKey());
436+
return $query->where($this->foreignPivotKey, $this->parent->getKey());
437437
}
438438

439439
/**

src/Illuminate/Database/Eloquent/Relations/MorphToMany.php

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,25 @@ class MorphToMany extends BelongsToMany
3838
* @param \Illuminate\Database\Eloquent\Model $parent
3939
* @param string $name
4040
* @param string $table
41-
* @param string $foreignKey
42-
* @param string $relatedKey
41+
* @param string $foreignPivotKey
42+
* @param string $relatedPivotKey
4343
* @param string $parentKey
44-
* @param string $localKey
44+
* @param string $relatedKey
4545
* @param string $relationName
4646
* @param bool $inverse
4747
* @return void
4848
*/
49-
public function __construct(Builder $query, Model $parent, $name, $table, $foreignKey,
50-
$relatedKey, $parentKey, $localKey, $relationName = null, $inverse = false)
49+
public function __construct(Builder $query, Model $parent, $name, $table, $foreignPivotKey,
50+
$relatedPivotKey, $parentKey, $relatedKey, $relationName = null, $inverse = false)
5151
{
5252
$this->inverse = $inverse;
5353
$this->morphType = $name.'_type';
5454
$this->morphClass = $inverse ? $query->getModel()->getMorphClass() : $parent->getMorphClass();
5555

56-
parent::__construct($query, $parent, $table, $foreignKey, $relatedKey, $parentKey, $localKey, $relationName);
56+
parent::__construct(
57+
$query, $parent, $table, $foreignPivotKey,
58+
$relatedPivotKey, $parentKey, $relatedKey, $relationName
59+
);
5760
}
5861

5962
/**
@@ -136,7 +139,7 @@ public function newPivot(array $attributes = [], $exists = false)
136139
$pivot = $using ? $using::fromRawAttributes($this->parent, $attributes, $this->table, $exists)
137140
: new MorphPivot($this->parent, $attributes, $this->table, $exists);
138141

139-
$pivot->setPivotKeys($this->foreignKey, $this->relatedKey)
142+
$pivot->setPivotKeys($this->foreignPivotKey, $this->relatedPivotKey)
140143
->setMorphType($this->morphType)
141144
->setMorphClass($this->morphClass);
142145

tests/Database/DatabaseEloquentModelTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,17 +1015,17 @@ public function testBelongsToManyCreatesProperRelation()
10151015
$this->addMockConnection($model);
10161016

10171017
$relation = $model->belongsToMany('Illuminate\Tests\Database\EloquentModelSaveStub');
1018-
$this->assertEquals('eloquent_model_save_stub_eloquent_model_stub.eloquent_model_stub_id', $relation->getQualifiedForeignKeyName());
1019-
$this->assertEquals('eloquent_model_save_stub_eloquent_model_stub.eloquent_model_save_stub_id', $relation->getQualifiedRelatedKeyName());
1018+
$this->assertEquals('eloquent_model_save_stub_eloquent_model_stub.eloquent_model_stub_id', $relation->getQualifiedForeignPivotKeyName());
1019+
$this->assertEquals('eloquent_model_save_stub_eloquent_model_stub.eloquent_model_save_stub_id', $relation->getQualifiedRelatedPivotKeyName());
10201020
$this->assertSame($model, $relation->getParent());
10211021
$this->assertInstanceOf('Illuminate\Tests\Database\EloquentModelSaveStub', $relation->getQuery()->getModel());
10221022
$this->assertEquals(__FUNCTION__, $relation->getRelationName());
10231023

10241024
$model = new EloquentModelStub;
10251025
$this->addMockConnection($model);
10261026
$relation = $model->belongsToMany('Illuminate\Tests\Database\EloquentModelSaveStub', 'table', 'foreign', 'other');
1027-
$this->assertEquals('table.foreign', $relation->getQualifiedForeignKeyName());
1028-
$this->assertEquals('table.other', $relation->getQualifiedRelatedKeyName());
1027+
$this->assertEquals('table.foreign', $relation->getQualifiedForeignPivotKeyName());
1028+
$this->assertEquals('table.other', $relation->getQualifiedRelatedPivotKeyName());
10291029
$this->assertSame($model, $relation->getParent());
10301030
$this->assertInstanceOf('Illuminate\Tests\Database\EloquentModelSaveStub', $relation->getQuery()->getModel());
10311031
}

0 commit comments

Comments
 (0)