NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages

Open source

Addresses for Laravel

Install
composer require roundly-consulting/addresses-for-laravel
Requires: PHP ^8.4 · Laravel ^13.0

Overview

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 the six built-in AddressType cases or your own configured types, with at most one primary address per type, promoted atomically, owner-checked updates and deletes, 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.

Configurable address types

Six built-in types — default, billing, shipping, home, work, office — or your own list in addresses.types. Unlisted types are refused on write; labels in English and Slovak.

One primary per type

Promoting an address demotes its siblings atomically, under a lock on the owner + type group. Owner-checked update, delete and setPrimary refuse another owner’s address.

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, allowed address types, default type, country normalisation, resolver and 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

Six built-in AddressType cases or your own types in addresses.types — writes refuse unlisted types; labels, ValidAddressType and select options.

The Addresses facade

Addresses::for($owner) returns an owner’s address book with owner-checked writes; flat update, delete, types and countryName need no owner.

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

Owner-checked or unscoped updates with 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, why they wait for the commit, 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 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 crypto

By 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.