Skip to content

Commit 171d8c2

Browse files
committed
-
1 parent b4d3dc1 commit 171d8c2

File tree

1 file changed

+62
-43
lines changed

1 file changed

+62
-43
lines changed

src/Eloquent/HybridRelations.php

+62-43
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace MongoDB\Laravel\Eloquent;
44

5+
use Illuminate\Database\Eloquent\Concerns\HasRelationships;
56
use Illuminate\Database\Eloquent\Model as EloquentModel;
67
use Illuminate\Database\Eloquent\Relations\MorphOne;
78
use Illuminate\Support\Str;
@@ -24,14 +25,16 @@ trait HybridRelations
2425
* Define a one-to-one relationship.
2526
*
2627
* @param class-string<EloquentModel> $related
27-
* @param string $foreignKey
28-
* @param string $localKey
28+
* @param string|null $foreignKey
29+
* @param string|null $localKey
2930
* @return \Illuminate\Database\Eloquent\Relations\HasOne
31+
*
32+
* @see HasRelationships::hasOne()
3033
*/
3134
public function hasOne($related, $foreignKey = null, $localKey = null)
3235
{
3336
// Check if it is a relation with an original model.
34-
if (! is_subclass_of($related, MongoDBModel::class)) {
37+
if (! self::isMongoDBModel($related)) {
3538
return parent::hasOne($related, $foreignKey, $localKey);
3639
}
3740

@@ -57,7 +60,7 @@ public function hasOne($related, $foreignKey = null, $localKey = null)
5760
public function morphOne($related, $name, $type = null, $id = null, $localKey = null)
5861
{
5962
// Check if it is a relation with an original model.
60-
if (! is_subclass_of($related, MongoDBModel::class)) {
63+
if (! self::isMongoDBModel($related)) {
6164
return parent::morphOne($related, $name, $type, $id, $localKey);
6265
}
6366

@@ -74,24 +77,24 @@ public function morphOne($related, $name, $type = null, $id = null, $localKey =
7477
* Define a one-to-many relationship.
7578
*
7679
* @param class-string<EloquentModel> $related
77-
* @param string $foreignKey
80+
* @param string $foreignPivotKey
7881
* @param string $localKey
7982
* @return \Illuminate\Database\Eloquent\Relations\HasMany
8083
*/
81-
public function hasMany($related, $foreignKey = null, $localKey = null)
84+
public function hasMany($related, $foreignPivotKey = null, $localKey = null)
8285
{
8386
// Check if it is a relation with an original model.
84-
if (! is_subclass_of($related, MongoDBModel::class)) {
85-
return parent::hasMany($related, $foreignKey, $localKey);
87+
if (! self::isMongoDBModel($related)) {
88+
return parent::hasMany($related, $foreignPivotKey, $localKey);
8689
}
8790

88-
$foreignKey = $foreignKey ?: $this->getForeignKey();
91+
$foreignPivotKey = $foreignPivotKey ?: $this->getForeignKey();
8992

9093
$instance = new $related;
9194

9295
$localKey = $localKey ?: $this->getKeyName();
9396

94-
return new HasMany($instance->newQuery(), $this, $foreignKey, $localKey);
97+
return new HasMany($instance->newQuery(), $this, $foreignPivotKey, $localKey);
9598
}
9699

97100
/**
@@ -103,11 +106,13 @@ public function hasMany($related, $foreignKey = null, $localKey = null)
103106
* @param string $id
104107
* @param string $localKey
105108
* @return \Illuminate\Database\Eloquent\Relations\MorphMany
109+
*
110+
* @see HasRelationships::morphMany()
106111
*/
107112
public function morphMany($related, $name, $type = null, $id = null, $localKey = null)
108113
{
109114
// Check if it is a relation with an original model.
110-
if (! is_subclass_of($related, MongoDBModel::class)) {
115+
if (! self::isMongoDBModel($related)) {
111116
return parent::morphMany($related, $name, $type, $id, $localKey);
112117
}
113118

@@ -129,12 +134,14 @@ public function morphMany($related, $name, $type = null, $id = null, $localKey =
129134
* Define an inverse one-to-one or many relationship.
130135
*
131136
* @param class-string<EloquentModel> $related
132-
* @param string $foreignKey
133-
* @param string $otherKey
137+
* @param string $foreignPivotKey
138+
* @param string $relatedPivotKey
134139
* @param string $relation
135140
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
141+
*
142+
* @see HasRelationships::belongsTo()
136143
*/
137-
public function belongsTo($related, $foreignKey = null, $otherKey = null, $relation = null)
144+
public function belongsTo($related, $foreignPivotKey = null, $relatedPivotKey = null, $relation = null)
138145
{
139146
// If no relation name was given, we will use this debug backtrace to extract
140147
// the calling method's name and use that as the relationship name as most
@@ -144,15 +151,15 @@ public function belongsTo($related, $foreignKey = null, $otherKey = null, $relat
144151
}
145152

146153
// Check if it is a relation with an original model.
147-
if (! is_subclass_of($related, MongoDBModel::class)) {
148-
return parent::belongsTo($related, $foreignKey, $otherKey, $relation);
154+
if (! self::isMongoDBModel($related)) {
155+
return parent::belongsTo($related, $foreignPivotKey, $relatedPivotKey, $relation);
149156
}
150157

151158
// If no foreign key was supplied, we can use a backtrace to guess the proper
152159
// foreign key name by using the name of the relationship function, which
153160
// when combined with an "_id" should conventionally match the columns.
154-
if ($foreignKey === null) {
155-
$foreignKey = Str::snake($relation).'_id';
161+
if ($foreignPivotKey === null) {
162+
$foreignPivotKey = Str::snake($relation).'_id';
156163
}
157164

158165
$instance = new $related;
@@ -162,9 +169,9 @@ public function belongsTo($related, $foreignKey = null, $otherKey = null, $relat
162169
// actually be responsible for retrieving and hydrating every relations.
163170
$query = $instance->newQuery();
164171

165-
$otherKey = $otherKey ?: $instance->getKeyName();
172+
$relatedPivotKey = $relatedPivotKey ?: $instance->getKeyName();
166173

167-
return new BelongsTo($query, $this, $foreignKey, $otherKey, $relation);
174+
return new BelongsTo($query, $this, $foreignPivotKey, $relatedPivotKey, $relation);
168175
}
169176

170177
/**
@@ -175,6 +182,8 @@ public function belongsTo($related, $foreignKey = null, $otherKey = null, $relat
175182
* @param string $id
176183
* @param string $ownerKey
177184
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
185+
*
186+
* @see HasRelationships::morphTo()
178187
*/
179188
public function morphTo($name = null, $type = null, $id = null, $ownerKey = null)
180189
{
@@ -214,23 +223,20 @@ public function morphTo($name = null, $type = null, $id = null, $ownerKey = null
214223
* Define a many-to-many relationship.
215224
*
216225
* @param class-string<EloquentModel> $related
217-
* @param string|null $collection
218-
* @param string|null $foreignKey
219-
* @param string|null $otherKey
220-
* @param string|null $parentKey
221-
* @param string|null $relatedKey
222-
* @param string|null $relation
226+
* @param string|null $collection
227+
* @param string|null $foreignPivotKey
228+
* @param string|null $relatedPivotKey
229+
* @param string|null $parentKey
230+
* @param string|null $relatedKey
231+
* @param string|null $relation
223232
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
233+
*
234+
* @see HasRelationships::belongsToMany()
224235
*/
225-
public function belongsToMany(
226-
$related,
227-
$collection = null,
228-
$foreignKey = null,
229-
$otherKey = null,
230-
$parentKey = null,
231-
$relatedKey = null,
232-
$relation = null
233-
) {
236+
public function belongsToMany($related, $collection = null, $foreignPivotKey = null, $relatedPivotKey = null,
237+
$parentKey = null, $relatedKey = null, $relation = null)
238+
{
239+
234240
// If no relationship name was passed, we will pull backtraces to get the
235241
// name of the calling function. We will use that function name as the
236242
// title of this relation since that is a great convention to apply.
@@ -239,12 +245,12 @@ public function belongsToMany(
239245
}
240246

241247
// Check if it is a relation with an original model.
242-
if (! is_subclass_of($related, MongoDBModel::class)) {
248+
if (! self::isMongoDBModel($related)) {
243249
return parent::belongsToMany(
244250
$related,
245251
$collection,
246-
$foreignKey,
247-
$otherKey,
252+
$foreignPivotKey,
253+
$relatedPivotKey,
248254
$parentKey,
249255
$relatedKey,
250256
$relation
@@ -255,11 +261,15 @@ public function belongsToMany(
255261
// First, we'll need to determine the foreign key and "other key" for the
256262
// relationship. Once we have determined the keys we'll make the query
257263
// instances as well as the relationship instances we need for this.
258-
$foreignKey = $foreignKey ?: $this->getForeignKey().'s';
264+
$foreignPivotKey = $foreignPivotKey ?: $this->getForeignKey().'s';
259265

260266
$instance = new $related;
261267

262-
$otherKey = $otherKey ?: $instance->getForeignKey().'s';
268+
if ($relatedPivotKey === $relation) {
269+
throw new \LogicException(sprintf('In %s::%s(), the key cannot be identical to the relation name "%s". The default key is "%s".', static::class, $relation, $relation, $instance->getForeignKey() . 's'));
270+
}
271+
272+
$relatedPivotKey = $relatedPivotKey ?: $instance->getForeignKey().'s';
263273

264274
// If no table name was provided, we can guess it by concatenating the two
265275
// models using underscores in alphabetical order. The two model names
@@ -277,8 +287,8 @@ public function belongsToMany(
277287
$query,
278288
$this,
279289
$collection,
280-
$foreignKey,
281-
$otherKey,
290+
$foreignPivotKey,
291+
$relatedPivotKey,
282292
$parentKey ?: $this->getKeyName(),
283293
$relatedKey ?: $instance->getKeyName(),
284294
$relation
@@ -304,10 +314,19 @@ protected function guessBelongsToManyRelation()
304314
*/
305315
public function newEloquentBuilder($query)
306316
{
307-
if (is_subclass_of($this, MongoDBModel::class)) {
317+
if (self::isMongoDBModel(static::class)) {
308318
return new Builder($query);
309319
}
310320

311321
return new EloquentBuilder($query);
312322
}
323+
324+
/**
325+
* @param class-string<EloquentModel> $model
326+
* @return bool
327+
*/
328+
final protected static function isMongoDBModel(string $model): bool
329+
{
330+
return is_subclass_of($model, MongoDBModel::class);
331+
}
313332
}

0 commit comments

Comments
 (0)