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.

00[1 issues](https://github.com/whilesmartphp/eloquent-contacts/issues)PHPCI passing

Since Jun 10Pushed todayCompare

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

READMEChangelog (2)DependenciesVersions (2)Used By (0)

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

21

—

LowBetter than 18% of packages

Maintenance65

Regular maintenance activity

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity13

Early-stage or recently created project

 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.

### 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)")

### 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

[jdorn/sql-formatter

a PHP SQL highlighting library

3.9k116.5M113](/packages/jdorn-sql-formatter)[propel/propel1

Propel is an open-source Object-Relational Mapping (ORM) for PHP5.

8361.6M87](/packages/propel-propel1)

PHPackages © 2026

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