inisiatif/model-shared
Kumpulan model Eloquent bersama untuk Inisiatif Zakat Indonesia: pekerjaan, tingkat pendidikan, wilayah (negara–provinsi–desa), dan status perkawinan. Mendukung relasi dinamis Branch dan Employee pada model Donor via resolveRelationUsing.
Installation
Run composer require inisiatif/model-shared in your Laravel project. Ensure your composer.json specifies Laravel 10+ compatibility if needed (check release notes).
Publish Migrations
Execute php artisan vendor:publish --provider="Inisiatif\ModelShared\ModelSharedServiceProvider" to publish migrations for all shared models (e.g., degrees, regions, donors). Run migrations with php artisan migrate.
First Use Case: Donor Model
Use the Donor model directly in your controllers:
use Inisiatif\ModelShared\Models\Donor;
$donor = Donor::create([
'name' => 'John Doe',
'email' => 'john@example.com', // Added in v2.10.1
'phone_id' => '12345', // Added in v2.10.2
'degree_id' => 1,
'marital_status_id' => 1,
]);
Dynamic Relations (Critical for Integration)
Configure dynamic relations in your AppServiceProvider’s boot() method (as shown in the README). Example:
Donor::resolveRelationUsing('branch', fn(Donor $donor) => $donor->belongsTo(\App\Models\Branch::class, 'branch_id'));
Seed Reference Data (Optional)
Use the package’s seeders (if provided) or manually seed degrees, regions, and other reference tables via php artisan db:seed --class=ModelSharedSeeder.
Region models (e.g., Province, District, Village) for location-based filtering:
$village = \Inisiatif\ModelShared\Models\Village::with('district.region.province')->find($id);
region-search API (added in v2.5.0) for autocomplete or bulk lookups:
$regions = \Inisiatif\ModelShared\Http\Controllers\RegionSearchController::search('Jakarta');
Donor model for custom logic (e.g., notifications):
use Inisiatif\ModelShared\Models\Donor;
class CustomDonor extends Donor {
protected static function booted() {
static::created(fn($donor) => notify($donor)->via('email')->send(new DonorRegistered()));
}
}
Donor (e.g., branch, employee) as shown in the README. Example for a custom Employee relation:
Donor::resolveRelationUsing('employee', fn(Donor $donor) =>
$donor->belongsTo(\App\Models\Employee::class, 'employee_id')
);
Outflow model (added in v2.9.0) to log disbursements:
$outflow = \Inisiatif\ModelShared\Models\Outflow::create([
'donor_id' => $donor->id,
'amount' => 1000000,
'category_id' => 1, // e.g., 'Food'
'status' => 'pending',
]);
Donation and DonationDetail (added in v2.7.3):
$donation = \Inisiatif\ModelShared\Models\Donation::create([
'donor_id' => $donor->id,
'amount' => 500000,
'type_id' => 1, // e.g., 'Cash'
]);
Degree model for standardized education fields:
$degree = \Inisiatif\ModelShared\Models\Degree::where('name', 'SMA')->first();
MaritalStatus model:
$status = \Inisiatif\ModelShared\Models\MaritalStatus::where('name', 'Menikah')->first();
config/app.php under providers:
Inisiatif\ModelShared\ModelSharedServiceProvider::class,
php artisan vendor:publish --tag=model-shared-config
DonorResource) in your app/Http/Resources:
namespace App\Http\Resources;
use Inisiatif\ModelShared\Http\Resources\DonorResource as BaseDonorResource;
class DonorResource extends BaseDonorResource {
public function toArray($request) {
$array = parent::toArray($request);
$array['custom_field'] = $this->customField;
return $array;
}
}
$donor = new Donor();
$donor->newQuery()->shouldReceive('belongsTo')
->with(\App\Models\Branch::class, 'branch_id')
->andReturn(new BelongsTo());
$village = \Inisiatif\ModelShared\Models\Village::factory()->create();
$this->assertEquals($village->district->region->name, 'DKI Jakarta');
with('district.region')) to avoid N+1 queries.Degree, MaritalStatus) in AppServiceProvider:
Cache::remember('degrees', now()->addHours(1), fn() =>
\Inisiatif\ModelShared\Models\Degree::all()
);
Dynamic Relations Overhead
Donor::branch) are resolved at runtime, which can impact performance if overused.Donor model:
public function branch() {
return $this->belongsTo(\App\Models\Branch::class, 'branch_id');
}
Migration Conflicts
donors, regions) if your project already has them.UUID vs. Increment ID
Partner in v2.8.2) use UUIDs, while others use auto-increment IDs. This can cause issues in polymorphic relations or foreign key constraints.morphMap if mixing UUIDs and increments:
class Donor extends Model {
public function getMorphClass() {
return 'donor';
}
}
Deprecated or Typo Fixes
account → accounts). Older versions may have broken migrations.Laravel Version Compatibility
composer.json for Laravel constraints.Dynamic Relation Errors
Call to undefined method when accessing dynamic relations (e.g., Donor::branch).AppServiceProvider::boot():
Donor::resolveRelationUsing('branch', fn($donor) => $donor->belongsTo(\App\Models\Branch::class, 'branch_id'));
dd($donor->getRelation('branch')) to inspect the relation.Geographic Data Inconsistencies
How can I help you explore Laravel packages today?