laravel / ideas

Issues board used for Laravel internals discussions.
938 stars 28 forks source link

$connection attribute on Pivot models #1583

Open tobysommer opened 5 years ago

tobysommer commented 5 years ago

Hi there,

currently a Illuminate\Database\Eloquent\Relations\Pivot-extending class always uses its parent $connection.

Given the following situation, where Model A is e.g. on a mysql connection and Model B is e.g. on a sqlsrv connection, the intermediate pivot table has to exists on the parent. Example:

// Model A

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

    public function bs() {
        return $this->belongsToMany(B::class)->using(AB::class);
    }
}
// Model B

class B extends Model {
    protected $connection = 'sqlsrv';
}
// Pivot AB

class AB extends Pivot {
    $connection = 'mysql'; // this is currently ignored!
}

the above code currently doesn't work; it's assumed, that the pivot table is on a sqlsrv connection.

Is there any chance to make this happen? Default can be the parents connection, but setting the protected $connection attribute can overwrite this?!

Any ideas/tips/etc?

Thanks in advance!

staudenmeir commented 5 years ago

This is not a Laravel issue, it's a technical limitation. An SQL query can't join multiple database systems, only databases on the same server (e.g. two MySQL databases).

A possible workaround is splitting the BelongsToMany relationship into a HasMany and a BelongsTo relationship.

tobysommer commented 5 years ago

Hi,

right, you can't join across multiple databases, but Laravel assumes that the Pivot (!) table lives on the parent's connection! But this doesn't have to; can't it reside on the other child's connection?!

staudenmeir commented 5 years ago

The pivot table can reside in both databases, but it has to reside in the same database as the related model. You can only query the relationship in one direction.

Applied to your example: When A and AB share the same connection, you can only define a relationship in the direction BA, but not AB.