Different db connection for models using hasManyThrough relationship in laravel 5.1
Asked Answered
S

2

9

I am trying to use the hasManyThrough relationship in laravel 5.1 but the sql query is not using the appropriate prefix defined in each connection for each model used. I have 3 models 2 of which use the same connection and one of them uses a different one. The only difference between the connections is the prefix the database is the same.

  • Model A has connection A which uses prefix A_
  • Model B has connection B which uses prefix B_
  • Model C has connection B which uses prefix B_

The relationship:

Inside Model B:

public function relationshipWithA()
{
    return $this->hasManyThrough(A::class, C::class, 'Cid', 'Aid');
}

The final query logic is correct but instead of using the B_ prefix for the joined tables its using the A_ prefix for all the tables in the query.

Is this a bug/limitation of laravel? Is there a solution to this or I will have to do manual join to achieve what I want?

Seifert answered 28/1, 2016 at 13:0 Comment(1)
laravel models will not work with different connections for relationships because eloquent uses SQL joins behind the scenes and that won't be possible with more than one DB connectionFunches
M
5

Other relationship types work with multiple database connections:

public function foos()
{
    return $this->belongsToMany(Foo::class, 'other_db.foos');
}

But hasManyThrough does not have the $table parameter in its signature, so the same solution is not applicable.

However,

You can make an imperfect workaround like this:

public function bars()
{
    return $this->belongsToMany(Bar::class, 'other_db.bars');
}

public function foos()
{
    $barIds = $this->bars->pluck('id');
    return Foo::whereIn('bar_id', $barIds);
}

It does not offer the exact same functionality (Since it is a different return-type), but fulfills the purpose for more simple things.

If you want, you can also replicate some more of the syntax by doing something like this:

protected $appends = [
    'foos',
];

/**
 * @return Foo[]
 */
public function getFoosAttribute()
{
    return $this->foos()->get();
}

That way you can still use it in your code like you would most of the time with a regular relationship (Meaning you can use $this->foos instead of $this->foos()->get())

Misappropriate answered 23/6, 2016 at 10:34 Comment(0)
A
-1

Actually, it seems to work fine if you specify the connections inside your model classes via the $connection property. I tested it (Laravel 5.5) between a MySQL and SQL connection using a morphMany relationship:

Account Model:

class Account extends Model
{
    protected $connection = 'sqlsrv';

    public function notifications()
    {
        return $this->morphMany(Notification::class, 'notifiable');
    }
}

Notification Model:

class Notification extends Model
{
    protected $connection = 'mysql';

    public function notifiable()
    {
        return $this->morphTo();
    }
}
Ammonic answered 17/4, 2018 at 22:18 Comment(1)
It might work for morphMany but this question is about hasManyThrough which doesn't work.Akin

© 2022 - 2024 — McMap. All rights reserved.