Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rodrigopedra/6d8b6c2e4be5e1cce66549fc079b3d26 to your computer and use it in GitHub Desktop.
Save rodrigopedra/6d8b6c2e4be5e1cce66549fc079b3d26 to your computer and use it in GitHub Desktop.
Laravel BelongsToMany in different connections
<?php
namespace App\Models;
use Illuminate\Database\ConnectionInterface;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class BelongsToManyInDifferentConnections extends BelongsToMany
{
public $connection;
public function __construct(
Builder $query,
Model $parent,
ConnectionInterface $connection,
$table,
$foreignKey,
$relatedKey,
$relationName = null
) {
$this->connection = $connection;
parent::__construct( $query, $parent, $table, $foreignKey, $relatedKey, $foreignKey, $relatedKey, $relationName );
}
/**
* Set the where clause for the relation query.
*
* @return $this
*/
protected function addWhereConstraints()
{
return $this;
}
protected function performJoin( $query = null )
{
$query = $query ?: $this->query;
$baseTable = $this->related->getTable();
$key = $baseTable . '.' . $this->related->getKeyName();
$idsQuery = $this->parent->getConnection()
->table( $this->table )
->distinct()
->select( $this->relatedKey );
if (!is_null( $this->parent->id )) {
$idsQuery->where( $this->parent->getForeignKey(), $this->parent->id );
}
$ids = $idsQuery->pluck( $this->relatedKey )->all();
$query->whereIn( $key, $ids );
return $query;
}
protected function aliasedPivotColumns()
{
$defaults = [ $this->foreignPivotKey, $this->relatedPivotKey ];
return collect( array_merge( $defaults, $this->pivotColumns ) )
->map( function ( $column ) {
if (!in_array( $column, [ 'created_at', 'updated_at' ] )) {
return $column;
}
return $this->related->getTable() . '.' . $column . ' as pivot_' . $column;
} )
->map( function ( $column ) {
if (!in_array( $column, [ $this->relatedKey ] )) {
return $column;
}
return $this->related->getTable() . '.' . $this->related->getKeyName() . ' as pivot_' . $column;
} )
->map( function ( $column ) {
if ($column !== $this->parent->getForeignKey()) {
return $column;
}
return $this->parent->getConnection()->raw( $this->parent->id . ' as pivot_' . $column );
} )
->unique()
->all();
}
/**
* Get a new plain query builder for the pivot table.
*
* @return \Illuminate\Database\Query\Builder
*/
public function newPivotStatement()
{
return $this->connection->table( $this->table );
}
}
<?php
namespace App\Models;
use Illuminate\Database\ConnectionInterface;
trait HasBelongsToManyInDifferentConnections
{
/**
* Define a many-to-many relationship.
*
* @param string $related
* @param ConnectionInterface $connection
* @param string $table
* @param string $foreignKey
* @param string $relatedKey
* @param string $relation
*
* @return BelongsToManyInDifferentConnections
*/
public function belongsToManyInDifferentConnections(
$related,
$table = null,
ConnectionInterface $connection = null,
$foreignKey = null,
$relatedKey = null,
$relation = null
) {
if (is_null( $relation )) {
$relation = $this->guessBelongsToManyRelation();
}
$instance = $this->newRelatedInstance( $related );
$foreignKey = $foreignKey ?: $this->getForeignKey();
$relatedKey = $relatedKey ?: $instance->getForeignKey();
if (is_null( $table )) {
$table = $this->joiningTable( $related );
}
if (is_null( $connection )) {
$connection = $this->getConnection();
}
return new BelongsToManyInDifferentConnections(
$instance->newQuery(), $this, $connection, $table, $foreignKey, $relatedKey, $relation
);
}
}
@emilianotisato
Copy link

Hello Rodrigo, thanks for this gist!!

It is working and saving records in pivot, but when I add withPivot() sql can't find the extra pivot columns because is looking for them in the second connection database.

I have this:

    public function businessCenters()
    {
        return $this->belongsToManyInDifferentConnections(BusinessCenter::class, 'account_business_center')
        ->withPivot('income', 'expense');
    }

Any idea why?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment