Laravel Nova跨数据库BelongsToMany关联异常求助
跨数据库多对多关联Nova查询中间表错误问题
环境信息
- Laravel版本:10.47.0
- Nova版本:4.23.0(Silver Surfer)
- PHP版本:8.2.13
- 数据库驱动及版本:MySQL 10.11.6-MariaDB-1:10.11.6+maria~deb11
- 操作系统及版本:Debian 11
- 浏览器类型及版本:Chrome 122.0.6261.95
- 复现仓库:无
问题描述
存在跨数据库多对多关联场景:Product模型使用corcel数据库连接,Distribution模型使用mysql数据库连接,中间表distribution_product存储在mysql库中。但Nova始终在corcel连接中查找该中间表,导致表不存在错误。尝试多种配置方案无效,Nova更新日志无相关修复记录,询问是配置错误还是Bug。
模型代码
Distribution模型
protected $connection = 'mysql'; public function product(): BelongsToMany { return $this->belongsToMany(Product::class)->withPivot('amount')->using(DistributionProduct::class); }
DistributionProduct 中间表模型
class DistributionProduct extends Pivot { protected $connection = 'mysql'; protected $table = 'distribution_product'; }
Product模型
class Product extends Model { protected $connection = 'corcel'; public function distribution(): BelongsToMany { return $this->belongsToMany(Distribution::class)->withPivot('amount')->using(DistributionProduct::class); } }
复现步骤
- 执行命令创建模型及迁移:
php artisan make:model -m Distribution php artisan make:model -m Product php artisan make:model -m DistributionProduct --pivot - 创建Nova资源:
php artisan nova:resource Distribution php artisan nova:resource Product - 执行迁移:
php artisan migrate - 在
config/database.php中添加corcel数据库连接配置 - 按照上述代码更新各模型
报错信息
{ "message": "SQLSTATE[42S02]: Base table or view not found: 1146 Table 'corcel_database.distribution_product' doesn't exist (Connection: corcel, SQL: select `posts`.*, `distribution_product`.`distribution_id` as `pivot_distribution_id`, `distribution_product`.`product_ID` as `pivot_product_ID`, `distribution_product`.`amount` as `pivot_amount` from `posts` inner join `distribution_product` on `posts`.`ID` = `distribution_product`.`product_ID` where `post_type` = product and `distribution_product`.`distribution_id` = 2)", "exception": "Illuminate\\Database\\QueryException", "file": "/vendor/laravel/framework/src/Illuminate/Database/Connection.php" }
解决方案
这并非Bug,是跨数据库关联时的默认行为导致:Laravel会默认使用发起查询的模型的数据库连接(此处Product模型用的是corcel连接),因此会去该库查找中间表。需要在关联定义中显式指定中间表的数据库连接,有两种方式:
方式一:关联中指定中间表的完整数据库+表名
修改Product模型的distribution关联:
public function distribution(): BelongsToMany { return $this->belongsToMany(Distribution::class, 'mysql.distribution_product') ->withPivot('amount') ->using(DistributionProduct::class); }
方式二:在关联中设置中间表的连接
修改Product模型的distribution关联:
public function distribution(): BelongsToMany { return $this->belongsToMany(Distribution::class) ->withPivot('amount') ->using(DistributionProduct::class) ->setConnection('mysql'); }
同理,若从Distribution模型发起查询,也需确保关联中指定正确的连接(不过此时默认会用Distribution的mysql连接,通常不会出问题)。
内容的提问来源于stack exchange,提问作者NoAd
相关产品推荐
相关产品推荐

