Skip to content

Exception : Call to undefined method Illuminate\Database\Eloquent\Relations\BelongsTo::getOwnerKey() #3385

Open
@waleedfaridworkland

Description

@waleedfaridworkland
  • Laravel-mongodb Version: 5.4.1
  • PHP Version: 8.2
  • Database Driver & Version: 2.0.0

Description:

We have a micro services architecture and we work with multiple databases within MySQL.

In our laravel-lumen application version 10, when we specify different mysql models using different database names through the connection property, while using HybridRelations, we get the error

Call to undefined method Illuminate\Database\Eloquent\Relations\BelongsToMany::getOwnerKeyName()

  1. Model A uses hybrid relations and its table resides in mysql database 1
  • It has a many to many relationship with Model B.
  • It also has a one to one relationship with Model C.
  • It has property protected $connection = database_1
  1. Model B does not use hybrid relations and its table resides in mysql database 2
  • It has a many to many relationship with Model A.
  • It has property protected $connection = database_2
  1. Model C has a collection that resides in MongoDB.

Expected behaviour

When querying Model A like so :

$candidateUserIds = A::whereHas('B', function ($query) use ($b_ids) {
$query->whereIn('b_table.id', $b_ids);
})->get();

It should return results, respecting the condition on its relationship.

Actual behaviour

Get the error :
Call to undefined method Illuminate\Database\Eloquent\Relations\BelongsToMany::getOwnerKeyName()

This is because of this function here :
mongodb > laravel-mongodb > src > Helpers > trait QueriesRelationships

public function has($relation, $operator = '>=', $count = 1, $boolean = 'and', ?Closure $callback = null)

In particular line 56 

    if (Model::isDocumentModel($this->getModel()) || $this->isAcrossConnections($relation)) {
        return $this->addHybridHas($relation, $operator, $count, $boolean, $callback);
    }

The following function returns true.

protected function isAcrossConnections(Relation $relation)
{
    return $relation->getParent()->getConnectionName() !== $relation->getRelated()->getConnectionName();
}

In my case both model A and model B are in mysql, but because they have different connection names, they are considered hybrid relationships and laravel thinks that Model B is in MongoDB.

The temporary fix was to remove the connection property from Model B and specify the database name in the property
protected $table = 'database_2.b_table';

Would it be possible to check the driver property of the connections instead ?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions