首页 > 解决方案 > 如何在 Laravel 中使用 Eloquent 创建动态模型?

问题描述

我正在重构一个旧数据库,我想快速查询/修改不同数据库中的表。

例如,我有 20 个以公司部门编号命名的不同数据库:

DbNameWeird-100
DbNameWeird-125
DbNameWeird-245
DbNameWeird-336
...

每个数据库都具有相同的结构。我想做的是一个完整的重构,而不是我可以做 20 个不同的连接:

Foo::where('department', 125)->all();

中期目标是通过department在每个表上添加一个新的主键列来将这些数据库合并在一起。但目前我只会这样做:

$foo = Foo($department);
$foo->all();

要朝这个方向发展,我需要建立联系:

foreach($departments as $dep) {
    DB::addConnection(dbConnection("DbNameWeird-{$dep}"), "db-{$dep}");
}

然后我需要动态更新protected $connection我的Foo模型。

为了用一块石头杀死两只鸟,我写了这个:

class Foo extends \Eloquent
{
    protected $table = 'foo';
    protected $connection;
    public $timestamps = false;

    protected $guarded = [];

    public function __construct($department) {
        DB::addConnection(dbConnection("DbNameWeird-{$department}"), "db-{$department}");

        $this->connection = "db-{$department}";
        parent::__construct();
    }
}

dd((new Foo(42))->all());

不幸的是,它不起作用。我收到此错误:

Too few arguments to function Foo::__construct(), 0 passed in
project/portal/vendor/illuminate/database/Eloquent/Model.php
on line 460 and exactly 1 expected

这段代码有什么问题?

标签: phplaraveleloquent

解决方案


使用推荐的解决方案

使用多个数据库连接

当使用多个时,您可以通过门面connections的连接方法访问每个连接。传递给该DB方法的值应对应于配置文件中列出的连接之一:nameconnectionconfig/database.php

$users = DB::connection('foo')->select(...);

您还可以使用连接实例上的 getPdo 方法访问原始的底层 PDO 实例:

$pdo = DB::connection()->getPdo();

如果您需要更改连接Eloquent models并且DB还不够

您还可以通过setConnection方法在运行时定义连接

$foo = (new Foo)->setConnection('DbNameWeird-100');
$foo->first(); // or $foo->all();

或者你可以像这样使用on 方法

Foo::on('DbNameWeird-100')->first();
Foo::on('DbNameWeird-125')->first();

推荐阅读