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

Laravel Locations Laravel Package

pharaonic/laravel-locations

Laravel Locations is a lightweight package that adds country, state, and city data to Laravel apps, with models, migrations, and helpers for seeding and querying locations. It makes address forms, regional filters, and location-aware features easier to build.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install with composer require pharaonic/laravel-locations, then publish the package assets: php artisan vendor:publish --provider="Pharaonic\Laravel\Locations\LocationsServiceProvider". Publish tags vary by version — run php artisan vendor:publish without a tag first and pick the locations-* entries you need (config, migrations, seeders).
  • Run php artisan migrate, then seed the location dataset. This is the step people miss: the package ships data, not just schema, so an empty countries/states/cities table is the usual "it installed but returns nothing" symptom.
  • Look first at the package's src/Models directory and its config file — that tells you the exact model namespaces, table names, and whether optional datasets (currencies, timezones, languages) are enabled.
  • First use case: a country → state → city cascade on a registration or checkout form. Seed once, then query Country::all() for the first select and lazy-load children by country_id / state_id.

Implementation Patterns

  • Relationships over raw queries. Treat Country, State, City as normal Eloquent models: $country->states, $state->cities, and belongsTo back up the chain. Store country_id, state_id, city_id on your own tables and reference them with foreign keys rather than storing free-text names.
  • Cascading selects. Expose small JSON endpoints (/locations/states/{country}, /locations/cities/{state}) that return id + display name, and cache them aggressively — the data is effectively static. Cache::remember("states.{$countryId}", ...) removes the query cost from every form render.
  • Eager loading. Addresses rendered in a list should use ->with('city.state.country'); the three-level chain is an easy N+1 otherwise.
  • Validation. Use exists:countries,id (or the model's table from config) in FormRequests, and validate the parent-child consistency yourself — exists won't catch a city that doesn't belong to the submitted state.
  • Localized names. The package stores per-locale name columns; resolve display names through an accessor or a small presenter so views never hardcode a column like name_en.
  • Testing. Seeding millions of city rows in every test is painful. Seed only the countries/states you assert on in a dedicated trait, or wrap location-dependent tests in a transaction against a pre-seeded snapshot database.
  • Integration tip: keep a thin application-level LocationRepository in front of the package models. When the package changes model namespaces or adds datasets, you patch one class instead of every controller.

Gotchas and Tips

  • 1.5.7 is a data-only patch. It deletes a duplicate ISO entry from the states dataset (PR #20). There is no API or schema change, so nothing breaks — but existing installs will not pick up the fix unless the seeder is re-run. Check whether the package seeder uses insert, upsert, or updateOrInsert before re-running it on a populated database, or you may duplicate rows instead of fixing them.
  • Duplicate ISO codes are a real hazard. The bug fixed here is the classic symptom: State::where('iso2', 'XX')->first() silently returns an arbitrary row when two exist. Use firstOrFail plus a unique index on (country_id, iso2) if you add your own lookups.
  • Don't hardcode IDs. Location IDs can shift between data releases as entries are added or removed. Resolve by ISO code or name at runtime, never by numeric ID in seeders, tests, or config.
  • Seeding is heavy. The full cities dataset is large; db:seed can exhaust memory or hit the default 60s timeout. Seed via a dedicated command, raise memory_limit, and consider disabling datasets you don't use in the config before migrating.
  • Table name collisions. If your app already has countries/states/cities tables, the package migrations will conflict. Configure table names or migrate before installing your own.
  • Stale caches after re-seed. If you cache country/state lists (you should), flush those keys as part of the deploy step that re-seeds — otherwise the deleted duplicate from 1.5.7 lingers in cache.
  • Extension points: the config typically lets you override model classes and toggle datasets; publish the config and point the model mapping at your own subclasses if you need extra columns or accessors rather than editing vendor files.
  • Upgrade note: pin ^1.5 and treat any 1.6.x as needing a re-seed review. Data patches like 1.5.7 are low-risk but invisible without an operational step, so add "re-seed locations" to your release checklist.
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.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route