PHPackages                             whilesmart/eloquent-contacts - 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. whilesmart/eloquent-contacts

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

whilesmart/eloquent-contacts
============================

Polymorphic contacts (people attached to customers, vendors, anything) for Laravel applications.

1.0.1(1mo ago)0116[1 issues](https://github.com/whilesmartphp/eloquent-contacts/issues)1MITPHPPHP ^8.2CI passing

Since Jun 10Pushed 1mo agoCompare

[ Source](https://github.com/whilesmartphp/eloquent-contacts)[ Packagist](https://packagist.org/packages/whilesmart/eloquent-contacts)[ RSS](/packages/whilesmart-eloquent-contacts/feed)WikiDiscussions dev Synced 1w ago

READMEChangelog (2)Dependencies (5)Versions (9)Used By (1)

whilesmart/eloquent-contacts
============================

[](#whilesmarteloquent-contacts)

Polymorphic contacts for Laravel: people (with name, email, phone, title) attached to any model, scoped to an owner through [`whilesmart/eloquent-owner-access`](https://github.com/whilesmartphp/eloquent-owner-access). An org customer with several people, a vendor with an AP desk, anything with humans behind it.

Install
-------

[](#install)

```
composer require whilesmart/eloquent-contacts
php artisan migrate

```

Routes register automatically under the `api` prefix with `auth:sanctum`. Set `CONTACTS_REGISTER_ROUTES=false` to mount them yourself.

Attaching contacts to a model
-----------------------------

[](#attaching-contacts-to-a-model)

```
use Whilesmart\Contacts\Traits\HasContacts;

class Customer extends Model
{
    use HasContacts;
}

$customer->contacts()->create([
    'owner_type' => Workspace::class,
    'owner_id' => $workspaceId,
    'first_name' => 'Jane',
    'last_name' => 'Doe',
    'email' => 'ap@acme.test',
    'title' => 'Accounts Payable',
    'address' => '12 Market St, Douala',
    'is_primary' => true,
]);

$customer->primaryContact?->email;       // recipient for billing
$customer->primaryContact?->full_name;   // "Jane Doe"
```

`contacts()` returns every contact; `primaryContact()` returns the one flagged primary. Only one contact per parent can be primary: setting `is_primary` on one demotes the others automatically.

Custom model
------------

[](#custom-model)

The Contact model is swappable. Publish the config and point `contacts.model` at your own class (extend the package model to add fields/casts/behaviour):

```
// config/contacts.php
'model' => \App\Models\Contact::class,
```

The trait relations, route binding, and controller all resolve the class from config, so your model is used everywhere.

UUID keys
---------

[](#uuid-keys)

Off by default (auto-incrementing integer ids). To use UUID primary keys, set `CONTACTS_UUIDS=true`(or `contacts.uuids` config) **before running the migration**. The migration then creates a `uuid` primary key and `uuid` morph columns, and the model generates an ordered UUID on create. This assumes the owner and contactable models also use UUID keys.

Endpoints
---------

[](#endpoints)

MethodPathPurposeGET`/api/contacts`List (filter by `owner_*`, `contactable_type` + `contactable_id`, `q`)POST`/api/contacts`CreateGET`/api/contacts/{contact}`ShowPUT/PATCH`/api/contacts/{contact}`UpdateDELETE`/api/contacts/{contact}`Soft deleteList a single parent's people with `/api/contacts?contactable_type=App\Models\Customer&contactable_id=42`.

###  Health Score

43

—

FairBetter than 89% of packages

Maintenance90

Actively maintained with recent releases

Popularity13

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% 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

45d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/a1ca6f6e01ecbfe6640ff410c4f0321054fb48d05a5f843c2b89887b90369bcd?d=identicon)[whilesmart](/maintainers/whilesmart)

---

Top Contributors

[![nfebe](https://avatars.githubusercontent.com/u/14317775?v=4)](https://github.com/nfebe "nfebe (6 commits)")

###  Code Quality

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/whilesmart-eloquent-contacts/health.svg)

```
[![Health](https://phpackages.com/badges/whilesmart-eloquent-contacts/health.svg)](https://phpackages.com/packages/whilesmart-eloquent-contacts)
```

###  Alternatives

[leantime/leantime

Open source project management system for non-project managers. Simple like Trello, powerful like Jira. Built with neurodiversity in mind.

10.2k4.0k](/packages/leantime-leantime)[anourvalar/eloquent-serialize

Laravel Query Builder (Eloquent) serialization

11223.5M33](/packages/anourvalar-eloquent-serialize)[statamic-rad-pack/runway

Eloquently manage your database models in Statamic.

135224.7k8](/packages/statamic-rad-pack-runway)[duncanmcclean/statamic-cargo

Comprehensive e-commerce addon for Statamic. Build bespoke e-commerce sites without the complexity.

3518.3k](/packages/duncanmcclean-statamic-cargo)

PHPackages © 2026

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