Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Addressable Laravel Package

polifonic/addressable

Polifonic Addressable is a Laravel package that adds polymorphic address support to Eloquent models. Attach reusable addresses to users, companies, or any model via a simple trait and manage them through an intuitive API.

View on GitHub
Deep Wiki
Context7

Getting Started

Before anything else, audit the source. With 1 star and zero dependents, treat this package as unreviewed third-party code: read src/, the migration stubs, and composer.json constraints before adding it to a production app.

Minimal setup:

composer require polifonic/addressable
php artisan vendor:publish --provider="Polifonic\Addressable\AddressableServiceProvider"
php artisan migrate

Check what the publish step emits — typically a config file and a migration creating an addresses table with a polymorphic addressable_type / addressable_id pair plus address fields (line 1, line 2, city, state, postal code, country, and often latitude/longitude or a type discriminator).

First use case — attach a shipping address to a User or Order:

use Polifonic\Addressable\Traits\Addressable; // verify exact namespace in src/

class User extends Model
{
    use Addressable;
}

$user->addresses()->create([
    'type'        => 'shipping',
    'line_1'      => '1 Main St',
    'city'        => 'Springfield',
    'postal_code' => '12345',
    'country'     => 'US',
]);

Where to look first, in order: the trait file (what relations and helpers it actually exposes), the migration stub (column names and nullability), then the config file (model swapping, table name). The README is likely thin — the source is the documentation.

Implementation Patterns

Polymorphic attachment as the core workflow. The value of the package is the morphMany relationship, so the idiomatic pattern is: one Address model, many addressable parents (User, Order, Company, Warehouse). Add the trait to each model that can own an address rather than duplicating address columns across tables.

Discriminate address roles with a type column, not separate tables. Most implementations carry a type or label field. Use it for billing / shipping / home / work and add scoped accessors:

public function shippingAddress()
{
    return $this->morphOne(Address::class, 'addressable')->where('type', 'shipping');
}

If the package doesn't ship these scopes, define them in your own model or a wrapper trait — don't fork the package for it.

Normalize at the boundary. Address input arrives as messy form data. Keep a FormRequest that validates and a small mapper that converts the request into the package's expected column shape. This isolates you from column-name quirks and makes swapping the package later a one-file change.

Copy, don't share. When an order should retain the address as it was at purchase time, clone the user's address into a new record owned by the order. A shared morph record means later edits to a profile silently rewrite historical orders — a classic bug in address packages.

Reuse for API and admin panels. Because the relation is standard Eloquent, $user->addresses loads into API resources, Filament/Nova relation managers, and Blade partials without adapters. Load with ->with('addresses') on index endpoints to avoid N+1.

Compose with geocoding/country packages. Keep geocoding (lat/lng population) in an observer or service that runs after save, not inside the package's model, so you retain control over API calls and failure handling.

Gotchas and Tips

  • Bus factor and maintenance risk. One star, no dependents, no visible community. Pin an exact version in composer.json, and be prepared to vendor the trait into your app. Budget for reading every line before trusting it with user PII.
  • Morph map collisions. If you use Relation::enforceMorphMap(), the stored addressable_type values will be your aliases, not FQCNs. Confirm the package doesn't hardcode class names in queries or factories.
  • Table and column name assumptions. The package's model likely hardcodes addresses and standard column names. If you need user_addresses or custom fields, check whether the config exposes table/model overrides before resorting to a subclass.
  • Nullability and partial addresses. Migrations in small packages frequently mark every field required. Real addresses are partial (no line 2, no state in many countries). Verify the migration and relax it in your own follow-up migration rather than editing vendor files.
  • Don't hardcode country/state lists. Validate against a maintained dataset (e.g., a countries package); form selectors and backend rules must agree or you'll reject valid international input.
  • Cascade deletes. A morphMany has no database-level foreign key, so deleting a user orphans addresses. Add a deleting observer or a cleanup job; the package almost certainly doesn't handle this.
  • Soft deletes interact badly with uniqueness. If you enforce "one default address per type per user" with a unique index, soft-deleted rows still occupy that slot. Use a partial index or clear the flag on delete.
  • Debugging. If $model->addresses returns empty, check (a) the trait is on the model, (b) the morph type in the DB matches what Eloquent writes (especially with morph maps), and (c) $fillable/$guarded on the package's Address model allows the fields you're passing — mass-assignment silently drops unknown keys.
  • Extension points to prefer. Config-driven model swap and a container binding for the address contract (if one exists) are the safe hooks. Avoid subclassing the package model just to add accessors — put those in your own presenter or API resource instead.
  • Test with factories you own. Don't rely on a vendor factory; write your own so a package update can't break your test suite's fixtures.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib