nurbekjummayev / laravel-region
Uzbekistan region and district (COATO) classifier for Laravel: migrations, seed data and Eloquent models with uz/oz/ru/en names
Requires
- php: ^8.3
- ext-json: *
- illuminate/console: ^13.0
- illuminate/database: ^13.0
- illuminate/support: ^13.0
Requires (Dev)
- laravel/pint: ^1.13
- orchestra/testbench: ^11.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Uzbekistan region and district (COATO) classifier for Laravel: migrations, seed data, and Eloquent models.
14 regions · 209 districts · Laravel 13 · PHP 8.3+
Installation
composer require nurbekjummayev/laravel-region
php artisan migrate php artisan region:seed
| Publish Tag | Content | Destination |
|---|---|---|
region-config |
region.php |
config/ |
region-migrations |
migrations | database/migrations/ |
region-data |
regions.json |
database/data/region/ |
Columns
Regions Table
| Column | Type | Description |
|---|---|---|
id |
bigint |
Auto-increment |
country_code |
char(2) |
Default UZ |
code |
string(8) |
COATO code, unique |
tax_code |
string(8) |
Tax authority code, unique |
type |
string |
republic, region, city |
name_uz |
string |
Uzbek name (Latin) |
name_oz |
string |
Uzbek name (Cyrillic) |
name_ru |
string |
Russian name |
name_en |
string |
English name |
is_active |
boolean |
Active/inactive |
timestamps |
created_at, updated_at |
Districts Table
| Column | Type | Description |
|---|---|---|
id |
bigint |
Auto-increment |
region_id |
bigint |
Foreign key to regions |
region_code |
string(8) |
Denormalized COATO |
code |
string(16) |
COATO code, nullable, unique |
tax_code |
string(8) |
Tax code, nullable |
type |
string |
district, city |
name_uz, name_oz, name_ru, name_en |
string |
Translated names |
is_active |
boolean |
Active/inactive |
timestamps |
created_at, updated_at |
Usage
use Nurbekjummayev\LaravelRegion\Models\Region; use Nurbekjummayev\LaravelRegion\Models\District; // Find by COATO code Region::findByCode('1735'); Region::findByTaxCode('35'); // Active regions with districts Region::active()->with('districts')->get(); // Find district District::findByCode('1735204'); District::query()->inRegion('1735')->get(); // Relationships $district = District::findByCode('1735204'); $district->region->name; // "Republic of Karakalpakstan" $district->name; // current locale
Finding District by Tax Code
District tax code is NOT globally unique — only unique within a region. Always search with region code:
District::findByTaxCode(regionCode: '1735', districtTaxCode: '8');
Translation
$region = Region::findByCode('1735'); $region->name; // Current locale $region->translatedName('ru'); // "Республика Каракалпакстан" $region->translatedName('en'); // "Republic of Karakalpakstan"
JSON Response
name is automatically appended (#[Appends]):
{
"code": "1735",
"name": "Republic of Karakalpakstan",
"type": "republic"
}
Route Model Binding
Models bind to routes by code:
// routes/web.php Route::get('/regions/{region}', fn (Region $region) => $region); Route::get('/districts/{district}', fn (District $district) => $district); // /regions/1735 → Region model // /districts/1735204 → District model
Inter-service Convention
Send
code(COATO), notid, to other services.
id is an internal auto-increment, different in each database.
code (COATO) is universal and immutable.
Data Notes
| Source | database/data/regions.json |
| Regions | 14 — code and tax_code globally unique |
| Districts | 209 — code globally unique |
| Region types | republic, region, city |
| District types | district, city |
⚠️ District tax_code |
NOT globally unique (23 duplicates). Composite unique(region_id, tax_code) applied |
| ⚠️ One district | Bo'z tumani (region 1703) has no code or tax_code in source. Both columns nullable. Seeder matches by (region_id, name_uz) |
districts.region_code is denormalized for fast lookup without joins.
Seeder is idempotent — safe to re-run.
Testing
composer test
composer lint
License
MIT License. See LICENSE for details.