Skip to content

Commit

Permalink
-
Browse files Browse the repository at this point in the history
  • Loading branch information
GromNaN committed Aug 30, 2023
1 parent b4d3dc1 commit 171d8c2
Showing 1 changed file with 62 additions and 43 deletions.
105 changes: 62 additions & 43 deletions src/Eloquent/HybridRelations.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace MongoDB\Laravel\Eloquent;

use Illuminate\Database\Eloquent\Concerns\HasRelationships;
use Illuminate\Database\Eloquent\Model as EloquentModel;
use Illuminate\Database\Eloquent\Relations\MorphOne;
use Illuminate\Support\Str;
Expand All @@ -24,14 +25,16 @@ trait HybridRelations
* Define a one-to-one relationship.
*
* @param class-string<EloquentModel> $related
* @param string $foreignKey
* @param string $localKey
* @param string|null $foreignKey
* @param string|null $localKey
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*
* @see HasRelationships::hasOne()
*/
public function hasOne($related, $foreignKey = null, $localKey = null)
{
// Check if it is a relation with an original model.
if (! is_subclass_of($related, MongoDBModel::class)) {
if (! self::isMongoDBModel($related)) {
return parent::hasOne($related, $foreignKey, $localKey);
}

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

Expand All @@ -74,24 +77,24 @@ public function morphOne($related, $name, $type = null, $id = null, $localKey =
* Define a one-to-many relationship.
*
* @param class-string<EloquentModel> $related
* @param string $foreignKey
* @param string $foreignPivotKey
* @param string $localKey
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function hasMany($related, $foreignKey = null, $localKey = null)
public function hasMany($related, $foreignPivotKey = null, $localKey = null)
{
// Check if it is a relation with an original model.
if (! is_subclass_of($related, MongoDBModel::class)) {
return parent::hasMany($related, $foreignKey, $localKey);
if (! self::isMongoDBModel($related)) {
return parent::hasMany($related, $foreignPivotKey, $localKey);
}

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

$instance = new $related;

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

return new HasMany($instance->newQuery(), $this, $foreignKey, $localKey);
return new HasMany($instance->newQuery(), $this, $foreignPivotKey, $localKey);
}

/**
Expand All @@ -103,11 +106,13 @@ public function hasMany($related, $foreignKey = null, $localKey = null)
* @param string $id
* @param string $localKey
* @return \Illuminate\Database\Eloquent\Relations\MorphMany
*
* @see HasRelationships::morphMany()
*/
public function morphMany($related, $name, $type = null, $id = null, $localKey = null)
{
// Check if it is a relation with an original model.
if (! is_subclass_of($related, MongoDBModel::class)) {
if (! self::isMongoDBModel($related)) {
return parent::morphMany($related, $name, $type, $id, $localKey);
}

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

// Check if it is a relation with an original model.
if (! is_subclass_of($related, MongoDBModel::class)) {
return parent::belongsTo($related, $foreignKey, $otherKey, $relation);
if (! self::isMongoDBModel($related)) {
return parent::belongsTo($related, $foreignPivotKey, $relatedPivotKey, $relation);
}

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

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

$otherKey = $otherKey ?: $instance->getKeyName();
$relatedPivotKey = $relatedPivotKey ?: $instance->getKeyName();

return new BelongsTo($query, $this, $foreignKey, $otherKey, $relation);
return new BelongsTo($query, $this, $foreignPivotKey, $relatedPivotKey, $relation);
}

/**
Expand All @@ -175,6 +182,8 @@ public function belongsTo($related, $foreignKey = null, $otherKey = null, $relat
* @param string $id
* @param string $ownerKey
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
*
* @see HasRelationships::morphTo()
*/
public function morphTo($name = null, $type = null, $id = null, $ownerKey = null)
{
Expand Down Expand Up @@ -214,23 +223,20 @@ public function morphTo($name = null, $type = null, $id = null, $ownerKey = null
* Define a many-to-many relationship.
*
* @param class-string<EloquentModel> $related
* @param string|null $collection
* @param string|null $foreignKey
* @param string|null $otherKey
* @param string|null $parentKey
* @param string|null $relatedKey
* @param string|null $relation
* @param string|null $collection
* @param string|null $foreignPivotKey
* @param string|null $relatedPivotKey
* @param string|null $parentKey
* @param string|null $relatedKey
* @param string|null $relation
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*
* @see HasRelationships::belongsToMany()
*/
public function belongsToMany(
$related,
$collection = null,
$foreignKey = null,
$otherKey = null,
$parentKey = null,
$relatedKey = null,
$relation = null
) {
public function belongsToMany($related, $collection = null, $foreignPivotKey = null, $relatedPivotKey = null,
$parentKey = null, $relatedKey = null, $relation = null)
{

// If no relationship name was passed, we will pull backtraces to get the
// name of the calling function. We will use that function name as the
// title of this relation since that is a great convention to apply.
Expand All @@ -239,12 +245,12 @@ public function belongsToMany(
}

// Check if it is a relation with an original model.
if (! is_subclass_of($related, MongoDBModel::class)) {
if (! self::isMongoDBModel($related)) {
return parent::belongsToMany(
$related,
$collection,
$foreignKey,
$otherKey,
$foreignPivotKey,
$relatedPivotKey,
$parentKey,
$relatedKey,
$relation
Expand All @@ -255,11 +261,15 @@ public function belongsToMany(
// First, we'll need to determine the foreign key and "other key" for the
// relationship. Once we have determined the keys we'll make the query
// instances as well as the relationship instances we need for this.
$foreignKey = $foreignKey ?: $this->getForeignKey().'s';
$foreignPivotKey = $foreignPivotKey ?: $this->getForeignKey().'s';

$instance = new $related;

$otherKey = $otherKey ?: $instance->getForeignKey().'s';
if ($relatedPivotKey === $relation) {
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'));
}

$relatedPivotKey = $relatedPivotKey ?: $instance->getForeignKey().'s';

// If no table name was provided, we can guess it by concatenating the two
// models using underscores in alphabetical order. The two model names
Expand All @@ -277,8 +287,8 @@ public function belongsToMany(
$query,
$this,
$collection,
$foreignKey,
$otherKey,
$foreignPivotKey,
$relatedPivotKey,
$parentKey ?: $this->getKeyName(),
$relatedKey ?: $instance->getKeyName(),
$relation
Expand All @@ -304,10 +314,19 @@ protected function guessBelongsToManyRelation()
*/
public function newEloquentBuilder($query)
{
if (is_subclass_of($this, MongoDBModel::class)) {
if (self::isMongoDBModel(static::class)) {
return new Builder($query);
}

return new EloquentBuilder($query);
}

/**
* @param class-string<EloquentModel> $model
* @return bool
*/
final protected static function isMongoDBModel(string $model): bool
{
return is_subclass_of($model, MongoDBModel::class);
}
}

0 comments on commit 171d8c2

Please sign in to comment.