Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MorphTo when changing db connection #29935

Closed
klimby opened this issue Sep 10, 2019 · 11 comments
Closed

MorphTo when changing db connection #29935

klimby opened this issue Sep 10, 2019 · 11 comments
Labels

Comments

@klimby
Copy link

klimby commented Sep 10, 2019

  • Laravel Version: 5.8.33
  • PHP Version: 7.2.15
  • Database Driver & Version: pgsql

Description:

MorphTo does not work when changing db connection.

Steps To Reproduce:

  1. Two identical databases - A end B
  2. Default connection - A
  3. The model Model contains:
public function element(): MorphTo
    {
        return $this->morphTo();
    }

$model = Model::with('element')->first();
$model->element contains object.

$model = Model::on('B')->with('element')->first();
$model->element is null
$model = $model -> load('element');
$model->element is null
$element = $model -> element() -> first();
$element is object.

  1. Set default connection to B.
    $model = Model::with('element')->first();
    $model->element contains object.

$model = Model::on('A')->with('element')->first();
$model->element is null

@driesvints
Copy link
Member

@klimby can you upgrade to 6.0 and see if the problem persists? I know quite some fixes to Eloquent have been made recently.

@klimby
Copy link
Author

klimby commented Sep 10, 2019

Updated to 6.0. Unfortunately, the problem is relevant.

@staudenmeir
Copy link
Contributor

I can reproduce this.

@adhyapranata
Copy link
Contributor

It works well with MySQL. Is this issue only occur with Postgres driver?

@staudenmeir
Copy link
Contributor

@adhyapranata The issue affects all databases.

@straube
Copy link

straube commented Oct 30, 2019

I couldn't reproduce this issue running Laravel 6.4.1 with MariaBD 10.3.16.

@driesvints
Copy link
Member

@straube can you try mysql or postgres?

@yaim
Copy link
Contributor

yaim commented Apr 28, 2020

@driesvints, @klimby, I traced the issue & found out that at @createModelByType, Eloquent lose track of the connection.

This workaround fixed the issue :

public function createModelByType($type)
{
    $class = Model::getActualClassNameForMorph($type);

    return (new $class)->setConnection($this->getConnection()->getName());
}

but it messes up with @testMorphToRelationsAcrossDatabaseConnections, as the test expects the Morph models to work on different connections (so the MorphTo model should define its connection by its own not using the other model).

This behavior seems totally right, as if we change it, then the ::on() method would override the protected $connection attribute, which probably breaks lots of logics.

Now I'm not sure if it's actually a bug or a planned feature. 🤔

@driesvints
Copy link
Member

@staudenmeir can you confirm the above? Is the current behavior correct?

@staudenmeir
Copy link
Contributor

AFAICS, we need to mimic the behavior of all other relationships and only set the connection on the related model if the parent model is not using the default connection.

protected function newRelatedInstance($class)
{
return tap(new $class, function ($instance) {
if (! $instance->getConnectionName()) {
$instance->setConnection($this->connection);
}
});
}

This fixes the issue for me and doesn't break testMorphToRelationsAcrossDatabaseConnections().

@yaim
Copy link
Contributor

yaim commented Apr 29, 2020

@staudenmeir you're right, that did work for me as well.
I thought getConnectionName would fallback to parent class's property.
I'm making a PR for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants