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
belongsTo
ke provinsi - WithRegency - Menambahkan relasi
belongsTo
ke kabupaten/kota - WithDistrict - Menambahkan relasi
belongsTo
ke kecamatan - WithVillage - Menambahkan relasi
belongsTo
ke desa/kelurahan - WithDistricts - Menambahkan relasi
hasMany
ke kecamatan - WithVillages - Menambahkan relasi
hasMany
ke 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
WithVillage
untuk lokasi paling spesifik - Gunakan
WithProvince
untuk pengelompokan regional - Gunakan
WithAddresses
untuk 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