Concern Model (Trait)
Laravel Nusa menyediakan kumpulan trait (concern) yang dapat digunakan kembali untuk menambahkan fungsionalitas wilayah administratif Indonesia ke model Anda sendiri. Trait ini memudahkan integrasi fitur berbasis lokasi ke dalam model aplikasi Anda.
Ringkasan
Concern model terletak di dalam namespace Creasi\Nusa\Models\Concerns dan menyediakan berbagai jenis relasi dan fungsionalitas:
Trait Relasi
- WithProvince - Menambahkan relasi
belongsToke provinsi - WithRegency - Menambahkan relasi
belongsToke kabupaten/kota - WithDistrict - Menambahkan relasi
belongsToke kecamatan - WithVillage - Menambahkan relasi
belongsToke desa/kelurahan - WithDistricts - Menambahkan relasi
hasManyke kecamatan - WithVillages - Menambahkan relasi
hasManyke desa/kelurahan dengan kode pos
Trait Manajemen Alamat
- WithAddress - Menambahkan relasi alamat polimorfik tunggal
- WithAddresses - Menambahkan relasi alamat polimorfik ganda
Trait Geografis
- WithCoordinate - Menambahkan fungsionalitas koordinat lintang/bujur
Contoh Penggunaan Umum
Profil Pengguna dengan Lokasi
use Creasi\Nusa\Models\Concerns\{WithProvince, WithRegency, WithDistrict, WithVillage};
class UserProfile extends Model
{
use WithProvince, WithRegency, WithDistrict, WithVillage;
protected $fillable = [
'name', 'email',
'province_code', 'regency_code', 'district_code', 'village_code'
];
}
// Penggunaan
$profile = UserProfile::with(['province', 'regency', 'district', 'village'])->first();
echo "Location: {$profile->village->name}, {$profile->district->name}, {$profile->regency->name}, {$profile->province->name}";Lokasi Bisnis
use Creasi\Nusa\Models\Concerns\{WithAddress, WithCoordinate};
class Store extends Model
{
use WithAddress, WithCoordinate;
protected $fillable = [
'name', 'description', 'latitude', 'longitude'
];
}
// Penggunaan
$store = Store::with('address')->first();
echo "Store: {$store->name} at {$store->latitude}, {$store->longitude}";Manajemen Regional
use Creasi\Nusa\Models\Concerns\{WithProvince, WithDistricts, WithVillages};
class RegionalOffice extends Model
{
use WithProvince, WithDistricts, WithVillages;
protected $fillable = ['name', 'province_code'];
}
// Penggunaan
$office = RegionalOffice::with(['province', 'districts', 'villages'])->first();
echo "Office covers {$office->districts->count()} districts and {$office->villages->count()} villages";Instalasi dan Pengaturan
1. Gunakan Trait di Model Anda
Cukup tambahkan pernyataan use untuk trait yang Anda butuhkan:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Creasi\Nusa\Models\Concerns\WithVillage;
class Customer extends Model
{
use WithVillage;
protected $fillable = ['name', 'email', 'village_code'];
}2. Migrasi Database
Pastikan tabel database Anda memiliki kolom foreign key yang sesuai:
Schema::create('customers', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email');
$table->string('village_code')->nullable();
$table->timestamps();
// Optional: Add foreign key constraint
$table->foreign('village_code')
->references('code')
->on('villages')
->onDelete('set null');
});3. Kustomisasi Nama Foreign Key
Anda dapat mengkustomisasi nama kolom foreign key dengan mendefinisikan properti:
class Customer extends Model
{
use WithVillage;
protected $villageKey = 'customer_village_code';
protected $fillable = ['name', 'email', 'customer_village_code'];
}Penggunaan Lanjutan
Dukungan Alamat Ganda
use Creasi\Nusa\Models\Concerns\WithAddresses;
class Company extends Model
{
use WithAddresses;
}
// Usage
$company = Company::first();
$company->addresses()->create([
'type' => 'headquarters',
'province_code' => '33',
'regency_code' => '33.75',
'district_code' => '33.75.01',
'village_code' => '33.75.01.1002',
'address_line' => 'Jl. Merdeka No. 123'
]);Kueri Geografis
use Creasi\Nusa\Models\Concerns\WithCoordinate;
class Event extends Model
{
use WithCoordinate;
}
// Find events within a radius
$nearbyEvents = Event::selectRaw('*, (
6371 * acos(
cos(radians(?)) * cos(radians(latitude)) *
cos(radians(longitude) - radians(?)) +
sin(radians(?)) * sin(radians(latitude))
)
) AS distance', [$lat, $lng, $lat])
->having('distance', '<', 10)
->orderBy('distance')
->get();Praktik Terbaik
1. Gunakan Trait yang Sesuai
Pilih trait berdasarkan kebutuhan model Anda:
- Gunakan
WithVillageuntuk lokasi paling spesifik - Gunakan
WithProvinceuntuk pengelompokan regional - Gunakan
WithAddressesuntuk model yang dapat memiliki banyak lokasi
2. Eager Loading
Selalu lakukan eager load pada relasi untuk menghindari kueri N+1:
$pelanggan = Pelanggan::with(['village.district.regency.province'])->get();3. Validasi
Validasi kode administratif dalam form request Anda:
public function rules()
{
return [
'village_code' => 'required|exists:nusa.villages,code',
'district_code' => 'required|exists:nusa.districts,code',
'regency_code' => 'required|exists:nusa.regencies,code',
'province_code' => 'required|exists:nusa.provinces,code',
];
}Dokumentasi Terkait
- Panduan Manajemen Alamat - Panduan lengkap penggunaan fungsionalitas alamat
- Model & Relasi - Memahami model inti Laravel Nusa
- Contoh Model Kustom - Contoh praktis penggunaan trait
- Contoh Formulir Alamat - Membangun formulir dengan wilayah administratif