Получить коллекцию отношений моделей из другой базы данных в Laravel

Я правильно настроил соединение с двумя базами данных. Я также создал красноречивые модели таблиц и могу легко запросить отношение одной таблицы из другой базы данных, например.

$user->customer

Модель пользователя

class User extends Model
{
  protected $connection = 'mysql';
  protected $table = 'users';
  
  
    public function customer()
    {
        return $this->hasMany(Customer::class, 'user_id', 'id');
    }

}

Модель клиента

class Customer extends Model
{
  protected $connection = 'second_db';
  protected $table = 'customers';
  
    public function order()
    {
        return $this->hasMany(Order::class, 'customer_id', 'id');
    }
}

Я могу получить данные о заказах во второй базе данных, используя этот простой запрос.

$customer->order

Но это дает пустой результат при запросе из первой базы данных с использованием

$user->customer->order

or 

$user->customer()->order

Как получить данные о взаимосвязях во втором дБ, запросив данные из первого дБ?

🤔 А знаете ли вы, что...
С PHP можно создавать кастомные расширения с помощью Си-кода.


60
2

Ответы:

Возможно, вам придется указать соединение внутри базового объекта Illuminate\Database\Query\Builder при быстрой загрузке.

$customers = Customer::query()
    ->with([
        'order' => function (HasMany $relation) {
            $eloquentBuilder = $relation->getQuery();
            $baseBuilder = $eloquentBuilder->getQuery();
            $baseBuilder->connection = DB::connection('mysql');
        },
    ])
    ->get();

Применяя это к вложенным отношениям:

$user = User::query()
    ->with(['customers' => function (HasMany $customers_relation) {
        $customers_relation
            ->getQuery()
            ->getQuery()
            ->connection = DB::connection('second_db');

        $customers_relation->with(['orders' => function (HasMany $orders_relation) {
            $orders_relation
                ->getQuery()
                ->getQuery()
                ->connection = DB::connection('mysql');
        }]);
    }])
    ...
    ->first();

Решено

Основываясь на требованиях ОП и ознакомившись с описанием в документации, вы можете попробовать HasManyThrough метод:

class User extends Model
{
    /**
     * Get all of the orders for the user.
     */
    public function orders(): HasManyThrough
    {
        return $this->hasManyThrough(Orders::class, Customer::class);
    }
}


// String based syntax...
return $user->through('customers')->has('orders');
 
// Dynamic syntax...
return $user->throughCustomers()->hasOrders();