Open source
Addresses for Laravel
composer require roundly-consulting/addresses-for-laravelOverview
Addresses for any Eloquent model, native to Laravel. Add the HasAddresses trait and attach as many billing, shipping, home or office addresses as you need through one polymorphic addresses table — created with a fluent builder or a DTO, typed by an AddressType enum, with at most one primary address per type, promoted atomically, and ISO country codes normalised on the way in. Query scopes, lifecycle events, an API resource and test helpers are included. MIT-licensed and built only on Laravel and Roundly’s own package toolkit — no third-party dependencies, no network calls.
What you get
Addresses on any model
One trait and one polymorphic table give any Eloquent model billing, shipping or office addresses — for bigint, UUID or ULID owners.
Typed address types
An AddressType enum — default, billing, shipping, home, work, office — with UI labels. No loose string types anywhere in the API.
One primary per type
Promoting an address demotes its siblings atomically, under a lock on the owner + type group; another owner’s or a deleted address is refused.
Facade, DI or actions
Addresses::for($customer)->new()->in(…)->at(…)->save() reads like a sentence; inject AddressManager or run an action for the same result.
ISO country normalisation
Codes are trimmed, upper-cased and shape-checked on write. Plug in your own CountryResolver for names and geocoding — no network calls.
Events, scopes & API resource
Four lifecycle events, primary/ofType/inCountry query scopes and a stable AddressResource for JSON APIs.
Recording fake & test helpers
Addresses::fake() records every write without touching the database, plus assertHasAddress(), assertPrimaryAddress() and an AddressFactory.
Documentation
Installation
Install via Composer, publish and run the addresses migration (set a UUID or ULID key type first), and optionally publish config/addresses.php.
Configuration
Every config key and its default — the address model, owner key type, default type, country normalisation, resolver and facade alias.
Database schema & key types
The addresses table column by column, and how key_type shapes the polymorphic owner column for bigint, UUID or ULID models.
The HasAddresses trait
Add HasAddresses to any Eloquent model for a polymorphic addresses relation plus create, read and primary-address helpers.
Address types
The AddressType enum — six cases with UI labels — and how to convert untrusted strings from requests safely.
The Addresses facade
Addresses::for($owner) returns an owner’s address book for any model; update, delete and countryName work on a single address.
DI and actions
Skip the facade: inject AddressManager or run one of the four actions directly — the facade method → action map.
AddressData & CreateAddressAction
Build writes with the AddressData DTO — make(), its defaults and the default_type fallback — or createAddress(), and run CreateAddressAction on any model.
Fluent builder
Create addresses with Addresses::for()->new() or newAddress() — a readable PendingAddress chain that refuses incomplete addresses.
Reading addresses
Fetch all addresses, the first or primary address of a type, a typed collection or a quick existence check.
Primary addresses
One primary address per owner and type — promote, demote, set it on create and guard against another owner’s address.
Query scopes
Filter addresses with the primary(), ofType() and inCountry() scopes — on the model, on any owner’s relation, or combined.
The Address model
Attributes, casts, the owner relation, JSON meta and the formatted() one-line label on the Address model.
Updating & deleting
Update with Addresses::update() and a full AddressData, soft-delete and restore addresses, and clean up when an owner goes.
Country codes & resolvers
ISO country normalisation on every write, plus an optional CountryResolver for names and geocoding — no bundled data, no network calls.
Events
AddressCreated, AddressUpdated, AddressDeleted and PrimaryAddressChanged — when each one fires and how to listen.
API resource
AddressResource renders an address for JSON APIs with a stable shape — lines, country, primary flag, formatted label and meta.
Custom address model
Swap in your own Address subclass through config to add scopes, relations or casts — every package path follows it.
Exceptions
One AddressesException base and five typed exceptions — incomplete address, invalid country, foreign address, deleted address and invalid type.
Testing
The recording Addresses::fake(), InteractsWithAddresses assertions, the AddressFactory with billing, shipping and primary states, and a Pest example.
Requirements
PHP 8.4+ and Laravel 12 or 13 — no PHP extensions, no third-party dependencies and no network calls.
Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.