Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force the write database connection on Laravel relationships

I'm using separate read and write connections in my Laravel app:

'mysql' => [
            'write' => ['host' => env('DB_HOST_WRITE', 'localhost'),],
            'read'  => ['host' => env('DB_HOST_READ', 'localhost'),],
            'driver' => 'mysql',
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'very'),
            'username' => env('DB_USERNAME', 'secret'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => false,
            'engine' => null,
        ],

Normally, if I'd like to force the write connection to be used, I'd write:

$user = User::onWriteConnection()->where('email', '[email protected]')->first();

This works just fine, directly on a model. But what if I have a case where I need to use the write connection throughout one specific method which uses relations, like this:

$user = User::find(123);

$user->universities()->attach(array(34, 56, 2));
$user->universities()->dettach(array(4, 78));

$primary = $user->universities()->where('primary', 1)->first();

// and so on...

I'd like all those relation-based operations (regardless whether they are, in fact, read or write ones) to be done on the write connection.

How do I do this in Laravel?

What I tried:

(1) Using the onWriteConnection() method on the relations - doesn't work due to the fact the method is static and directly connected to the Eloquent Model object.

(2) Using the setConnection() method:

$user = User::find(123);
$user->setConnection('mysql.write');

which throws the error that the driver index is not specified for the connection - which makes sense and proves it's not the right way to do it.

like image 359
lesssugar Avatar asked Jul 25 '17 12:07

lesssugar


1 Answers

You could directly use the useWritePdo() method of the query builder, which onWriteConnection() calls behind the scene:

$primary = $user->universities()->useWritePdo()->where('primary', 1)->first();
like image 137
thefallen Avatar answered Sep 20 '22 02:09

thefallen