nowox
nowox

Reputation: 29066

How to create a dynamic Model with Eloquent in Laravel?

I am refactoring an old database and I would like to quickly query/modify a table in different databases.

For instance I have 20 different databases named with company department numbers:

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

Each database have the same structure. What I would like to do is a full refactoring where instead of having 20 different connections I could do:

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

To goal in mid-term is to merge these databases together by adding a new primary key column named department on each table. But currently I would simply do:

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

To go in this direction I need to get my connections:

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

Then I need to dynamically update the protected $connection of my Foo model.

To kill two birds with one stone I wrote this:

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());

Unfortunately it does not work. I get this error:

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

What's wrong with this code?

Upvotes: 1

Views: 1647

Answers (1)

Aria Radmand
Aria Radmand

Reputation: 331

Use the recommended solution:

Using Multiple Database Connections

When using multiple connections, you may access each connection via the connection method on the DB facade. The name passed to the connection method should correspond to one of the connections listed in your config/database.php configuration file:

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

You may also access the raw, underlying PDO instance using the getPdo method on a connection instance:

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

If you need to change connections on Eloquent models and DB is not enough:

You can also define the connection at runtime via the setConnection method

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

Or you can use the on method like this:

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

Upvotes: 1

Related Questions