2
2
3
3
namespace MongoDB \Laravel \Eloquent ;
4
4
5
+ use Illuminate \Database \Eloquent \Concerns \HasRelationships ;
5
6
use Illuminate \Database \Eloquent \Model as EloquentModel ;
6
7
use Illuminate \Database \Eloquent \Relations \MorphOne ;
7
8
use Illuminate \Support \Str ;
@@ -24,14 +25,16 @@ trait HybridRelations
24
25
* Define a one-to-one relationship.
25
26
*
26
27
* @param class-string<EloquentModel> $related
27
- * @param string $foreignKey
28
- * @param string $localKey
28
+ * @param string|null $foreignKey
29
+ * @param string|null $localKey
29
30
* @return \Illuminate\Database\Eloquent\Relations\HasOne
31
+ *
32
+ * @see HasRelationships::hasOne()
30
33
*/
31
34
public function hasOne ($ related , $ foreignKey = null , $ localKey = null )
32
35
{
33
36
// Check if it is a relation with an original model.
34
- if (! is_subclass_of ($ related, MongoDBModel::class )) {
37
+ if (! self :: isMongoDBModel ($ related )) {
35
38
return parent ::hasOne ($ related , $ foreignKey , $ localKey );
36
39
}
37
40
@@ -57,7 +60,7 @@ public function hasOne($related, $foreignKey = null, $localKey = null)
57
60
public function morphOne ($ related , $ name , $ type = null , $ id = null , $ localKey = null )
58
61
{
59
62
// Check if it is a relation with an original model.
60
- if (! is_subclass_of ($ related, MongoDBModel::class )) {
63
+ if (! self :: isMongoDBModel ($ related )) {
61
64
return parent ::morphOne ($ related , $ name , $ type , $ id , $ localKey );
62
65
}
63
66
@@ -74,24 +77,24 @@ public function morphOne($related, $name, $type = null, $id = null, $localKey =
74
77
* Define a one-to-many relationship.
75
78
*
76
79
* @param class-string<EloquentModel> $related
77
- * @param string $foreignKey
80
+ * @param string $foreignPivotKey
78
81
* @param string $localKey
79
82
* @return \Illuminate\Database\Eloquent\Relations\HasMany
80
83
*/
81
- public function hasMany ($ related , $ foreignKey = null , $ localKey = null )
84
+ public function hasMany ($ related , $ foreignPivotKey = null , $ localKey = null )
82
85
{
83
86
// 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 );
86
89
}
87
90
88
- $ foreignKey = $ foreignKey ?: $ this ->getForeignKey ();
91
+ $ foreignPivotKey = $ foreignPivotKey ?: $ this ->getForeignKey ();
89
92
90
93
$ instance = new $ related ;
91
94
92
95
$ localKey = $ localKey ?: $ this ->getKeyName ();
93
96
94
- return new HasMany ($ instance ->newQuery (), $ this , $ foreignKey , $ localKey );
97
+ return new HasMany ($ instance ->newQuery (), $ this , $ foreignPivotKey , $ localKey );
95
98
}
96
99
97
100
/**
@@ -103,11 +106,13 @@ public function hasMany($related, $foreignKey = null, $localKey = null)
103
106
* @param string $id
104
107
* @param string $localKey
105
108
* @return \Illuminate\Database\Eloquent\Relations\MorphMany
109
+ *
110
+ * @see HasRelationships::morphMany()
106
111
*/
107
112
public function morphMany ($ related , $ name , $ type = null , $ id = null , $ localKey = null )
108
113
{
109
114
// Check if it is a relation with an original model.
110
- if (! is_subclass_of ($ related, MongoDBModel::class )) {
115
+ if (! self :: isMongoDBModel ($ related )) {
111
116
return parent ::morphMany ($ related , $ name , $ type , $ id , $ localKey );
112
117
}
113
118
@@ -129,12 +134,14 @@ public function morphMany($related, $name, $type = null, $id = null, $localKey =
129
134
* Define an inverse one-to-one or many relationship.
130
135
*
131
136
* @param class-string<EloquentModel> $related
132
- * @param string $foreignKey
133
- * @param string $otherKey
137
+ * @param string $foreignPivotKey
138
+ * @param string $relatedPivotKey
134
139
* @param string $relation
135
140
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
141
+ *
142
+ * @see HasRelationships::belongsTo()
136
143
*/
137
- public function belongsTo ($ related , $ foreignKey = null , $ otherKey = null , $ relation = null )
144
+ public function belongsTo ($ related , $ foreignPivotKey = null , $ relatedPivotKey = null , $ relation = null )
138
145
{
139
146
// If no relation name was given, we will use this debug backtrace to extract
140
147
// 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
144
151
}
145
152
146
153
// 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 );
149
156
}
150
157
151
158
// If no foreign key was supplied, we can use a backtrace to guess the proper
152
159
// foreign key name by using the name of the relationship function, which
153
160
// 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 ' ;
156
163
}
157
164
158
165
$ instance = new $ related ;
@@ -162,9 +169,9 @@ public function belongsTo($related, $foreignKey = null, $otherKey = null, $relat
162
169
// actually be responsible for retrieving and hydrating every relations.
163
170
$ query = $ instance ->newQuery ();
164
171
165
- $ otherKey = $ otherKey ?: $ instance ->getKeyName ();
172
+ $ relatedPivotKey = $ relatedPivotKey ?: $ instance ->getKeyName ();
166
173
167
- return new BelongsTo ($ query , $ this , $ foreignKey , $ otherKey , $ relation );
174
+ return new BelongsTo ($ query , $ this , $ foreignPivotKey , $ relatedPivotKey , $ relation );
168
175
}
169
176
170
177
/**
@@ -175,6 +182,8 @@ public function belongsTo($related, $foreignKey = null, $otherKey = null, $relat
175
182
* @param string $id
176
183
* @param string $ownerKey
177
184
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
185
+ *
186
+ * @see HasRelationships::morphTo()
178
187
*/
179
188
public function morphTo ($ name = null , $ type = null , $ id = null , $ ownerKey = null )
180
189
{
@@ -214,23 +223,20 @@ public function morphTo($name = null, $type = null, $id = null, $ownerKey = null
214
223
* Define a many-to-many relationship.
215
224
*
216
225
* @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
223
232
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
233
+ *
234
+ * @see HasRelationships::belongsToMany()
224
235
*/
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
+
234
240
// If no relationship name was passed, we will pull backtraces to get the
235
241
// name of the calling function. We will use that function name as the
236
242
// title of this relation since that is a great convention to apply.
@@ -239,12 +245,12 @@ public function belongsToMany(
239
245
}
240
246
241
247
// Check if it is a relation with an original model.
242
- if (! is_subclass_of ($ related, MongoDBModel::class )) {
248
+ if (! self :: isMongoDBModel ($ related )) {
243
249
return parent ::belongsToMany (
244
250
$ related ,
245
251
$ collection ,
246
- $ foreignKey ,
247
- $ otherKey ,
252
+ $ foreignPivotKey ,
253
+ $ relatedPivotKey ,
248
254
$ parentKey ,
249
255
$ relatedKey ,
250
256
$ relation
@@ -255,11 +261,15 @@ public function belongsToMany(
255
261
// First, we'll need to determine the foreign key and "other key" for the
256
262
// relationship. Once we have determined the keys we'll make the query
257
263
// instances as well as the relationship instances we need for this.
258
- $ foreignKey = $ foreignKey ?: $ this ->getForeignKey ().'s ' ;
264
+ $ foreignPivotKey = $ foreignPivotKey ?: $ this ->getForeignKey ().'s ' ;
259
265
260
266
$ instance = new $ related ;
261
267
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 ' ;
263
273
264
274
// If no table name was provided, we can guess it by concatenating the two
265
275
// models using underscores in alphabetical order. The two model names
@@ -277,8 +287,8 @@ public function belongsToMany(
277
287
$ query ,
278
288
$ this ,
279
289
$ collection ,
280
- $ foreignKey ,
281
- $ otherKey ,
290
+ $ foreignPivotKey ,
291
+ $ relatedPivotKey ,
282
292
$ parentKey ?: $ this ->getKeyName (),
283
293
$ relatedKey ?: $ instance ->getKeyName (),
284
294
$ relation
@@ -304,10 +314,19 @@ protected function guessBelongsToManyRelation()
304
314
*/
305
315
public function newEloquentBuilder ($ query )
306
316
{
307
- if (is_subclass_of ( $ this , MongoDBModel ::class)) {
317
+ if (self :: isMongoDBModel ( static ::class)) {
308
318
return new Builder ($ query );
309
319
}
310
320
311
321
return new EloquentBuilder ($ query );
312
322
}
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
+ }
313
332
}
0 commit comments