Define separate read and write database connections per Eloquent model.
Laravel has built-in support for read/write connection splitting, but it's configured at the connection level in config/database.php which means, every model using that connection shares the same read/write behaviour:
// config/database.php ...this applies globally to all models on this connection
'mysql' => [
'read' => ['host' => '192.168.1.2'],
'write' => ['host' => '196.168.1.3'],
],There's no first-party way to set specific models to only read. The alternative is manually calling ::on() or ->setConnection() everywhere you query, which is easy to forget and scatters connection logic across your codebase:
// Without this package ...you have to remember to do this every time
User::on('mysql_replica')->where('active', true)->get();
Post::on('mysql_replica')->latest()->get();This package gives you control over read and write connections per model without touching your connection config, and without sprinkling ::on() calls throughout your code. This is extremely useful if you know certain models can be deferred to a replica, and certain models are required instantly.
- Laravel 12
composer require jackbayliss/laravel-model-connectionAdd the HasReadWriteConnection trait to your model and define $readConnection and $writeConnection:
use JackBayliss\LaravelModelConnection\Traits\HasReadWriteConnection;
class User extends Model
{
use HasReadWriteConnection;
protected $readConnection = 'mysql_replica';
protected $writeConnection = 'mysql_primary';
}All reads (first(), get(), relationships, eager loads) will go to mysql_replica, and all writes (create(), update(), delete()) will go to mysql_primary.
If $readConnection or $writeConnection are not set, the trait falls back to the model's default $connection.
You can use a backed enum instead of a plain string:
enum DatabaseConnection: string
{
case Primary = 'mysql_primary';
case Replica = 'mysql_replica';
}
class User extends Model
{
use HasReadWriteConnection;
protected $readConnection = DatabaseConnection::Replica;
protected $writeConnection = DatabaseConnection::Primary;
}You can override the connections at runtime using the fluent setters:
$user = (new User)
->setReadConnection('mysql_replica_2')
->setWriteConnection('mysql_primary_2');| Method | Description |
|---|---|
getReadConnection() |
Returns the Connection instance for reads |
getWriteConnection() |
Returns the Connection instance for writes |
getReadConnectionName() |
Returns the read connection name as a string |
getWriteConnectionName() |
Returns the write connection name as a string |
setReadConnection($connection) |
Override the read connection at runtime |
setWriteConnection($connection) |
Override the write connection at runtime |
By default, factories will write to your model's $writeConnection (default if empty). In a real application this is correct as replication will sync the data to your read replica.
However, in tests you typically want factory-created records to be immediately readable via the model. Since reads go to $readConnection, you need factory writes to land there too.
Add the HasReadWriteConnectionFactory trait to your factory:
use JackBayliss\LaravelModelConnection\Traits\HasReadWriteConnectionFactory;
class UserFactory extends Factory
{
use HasReadWriteConnectionFactory;
protected $model = User::class;
public function definition(): array
{
return [
'name' => fake()->name(),
];
}
}This redirects the factory's save to the read connection, so User::factory()->create() produces records that User::find(), User::get(), etc. can retrieve.
If you already have a configure() method, call withReadWriteConnection() inside it instead:
public function configure(): static
{
return $this->withReadWriteConnection()->afterCreating(function (User $user) {
// your own logic
});
}The package includes a full test suite covering read/write routing, enum support, runtime overrides, and fallback behaviour. To run the tests:
composer testPlease see CONTRIBUTING for details.
Please review our security policy on how to report security vulnerabilities.
The MIT License (MIT). Please see License File for more information.