Когда вы работаете с несколькими базами данных в Laravel, есть один довольно хитрый подвох при использовании жадной загрузки (eager loading) и он легко может сбить вас с толку.
Представьте, что в вашем приложении есть две модели:
Order- хранится в внешней базе данных;Customer- живёт в основной (дефолтной) базе данных.
Примерно так:
class Order extends Model
{
protected $connection = 'external';
public function customer(): BelongsTo
{
return $this->belongsTo(Customer::class);
}
}
class Customer extends Model
{
// использует базу по умолчанию
}Вы могли бы логично ожидать, что при выполнении запроса:
Order::with('customer')->get();Laravel получит заказы из внешней базы данных (external) и отдельно клиентов из основной (mysql), как указано в настройках. Но на практике это не работает так, как кажется.
Фреймворк пытается найти таблицу customers в той же базе данных, что и заказы, то есть в external. Это приведёт к ошибке, потому что таблицы там просто нет.
Почему так происходит
В Laravel при eager loading создаётся новый экземпляр модели, на который затем накладываются ограничения для связи. Но если связанная модель не имеет явного свойства $connection, то Laravel автоматически унаследует соединение родителя.
А это означает, что связь customer будет искать customers в той же базе данных, что и orders, то есть в external, хотя мы хотим, чтобы она использовала дефолтную базу.
Как исправить
Решение простое: всегда указывайте свойство $connection даже для модели, которая должна использовать стандартное соединение. Так Laravel не будет приписывать ей внешний connection от родителя.
В итоге модель Customer должна выглядеть так:
class Customer extends Model
{
protected $connection = 'mysql';
}Теперь запрос Order::with('customer')->get() будет работать корректно: заказы получаются из external, а данные клиентов из mysql.