PHPackages                             jackbayliss/laravel-model-connection - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. jackbayliss/laravel-model-connection

ActiveLibrary[Database &amp; ORM](/categories/database)

jackbayliss/laravel-model-connection
====================================

Define separate read/write database connections per Eloquent model.

v1.0.1(2mo ago)61MITPHPPHP ^8.3CI passing

Since Feb 21Pushed 2mo agoCompare

[ Source](https://github.com/jackbayliss/laravel-model-connections)[ Packagist](https://packagist.org/packages/jackbayliss/laravel-model-connection)[ RSS](/packages/jackbayliss-laravel-model-connection/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (6)Versions (6)Used By (0)

Laravel Model Connections
=========================

[](#laravel-model-connections)

[![Latest Version on Packagist](https://camo.githubusercontent.com/1e01f813ac60a68b7438d8374c12fe9ac993dee952fdb84b401c9437dc05565f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6a61636b6261796c6973732f6c61726176656c2d6d6f64656c2d636f6e6e656374696f6e2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/jackbayliss/laravel-model-connection) [![GitHub Tests Action Status](https://camo.githubusercontent.com/ff0bd9236617dea372391664466a50337e64b849010603b5efaf0e15f845216b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6a61636b6261796c6973732f6c61726176656c2d6d6f64656c2d636f6e6e656374696f6e732f74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/jackbayliss/laravel-model-connections/actions/workflows/tests.yml?query=branch%3Amain)

Define separate read and write database connections per Eloquent model.

Why?
----

[](#why)

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.

Supports
--------

[](#supports)

- Laravel 12

Installation
------------

[](#installation)

```
composer require jackbayliss/laravel-model-connection
```

Usage
-----

[](#usage)

Add 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`.

Enum Support
------------

[](#enum-support)

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;
}
```

Runtime Override
----------------

[](#runtime-override)

You can override the connections at runtime using the fluent setters:

```
$user = (new User)
    ->setReadConnection('mysql_replica_2')
    ->setWriteConnection('mysql_primary_2');
```

Available Methods
-----------------

[](#available-methods)

MethodDescription`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 runtimeUsing with Factories
--------------------

[](#using-with-factories)

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
    });
}
```

Testing
-------

[](#testing)

The package includes a full test suite covering read/write routing, enum support, runtime overrides, and fallback behaviour. To run the tests:

```
composer test
```

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Jack Bayliss](https://github.com/jackbayliss)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance83

Actively maintained with recent releases

Popularity6

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 89.2% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

87d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/79e2e2281e64b7800db09d468ce14156b604138636efd6f85c7b6b8d2f0994b7?d=identicon)[jackbayliss](/maintainers/jackbayliss)

---

Top Contributors

[![jackbayliss](https://avatars.githubusercontent.com/u/13621738?v=4)](https://github.com/jackbayliss "jackbayliss (33 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (4 commits)")

---

Tags

laraveldatabaseeloquentread-writeconnections

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/jackbayliss-laravel-model-connection/health.svg)

```
[![Health](https://phpackages.com/badges/jackbayliss-laravel-model-connection/health.svg)](https://phpackages.com/packages/jackbayliss-laravel-model-connection)
```

###  Alternatives

[mongodb/laravel-mongodb

A MongoDB based Eloquent model and Query builder for Laravel

7.1k7.2M71](/packages/mongodb-laravel-mongodb)[spiritix/lada-cache

A Redis based, automated and scalable database caching layer for Laravel

591444.8k2](/packages/spiritix-lada-cache)[pdphilip/elasticsearch

An Elasticsearch implementation of Laravel's Eloquent ORM

145360.2k4](/packages/pdphilip-elasticsearch)[toponepercent/baum

Baum is an implementation of the Nested Set pattern for Eloquent models.

3154.7k](/packages/toponepercent-baum)[czim/laravel-filter

Filter for Laravel Eloquent queries, with support for modular filter building

8973.0k3](/packages/czim-laravel-filter)[eusonlito/laravel-database-cache

Cache Database Query results on Laravel Query Builder or Eloquent

194.2k](/packages/eusonlito-laravel-database-cache)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
