Weave Code
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

Vietnam Maps Laravel Package

hoangphi/vietnam-maps

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require hoangphi/vietnam-maps
    php artisan vietnam-map:install
    

    This runs the default installation, publishing config and migrations, then imports the dataset into vietnam_maps_provinces, vietnam_maps_districts, and vietnam_maps_wards tables.

  2. First Use Case: Fetch all provinces with their districts:

    use HoangPhi\VietnamMap\Models\Province;
    use HoangPhi\VietnamMap\Models\District;
    
    $provinces = Province::with('districts')->get();
    foreach ($provinces as $province) {
        echo $province->name;
        foreach ($province->districts as $district) {
            echo " - {$district->name}";
        }
    }
    

Where to Look First

  • Config: config/vietnam-maps.php (customize table/column names).
  • Models: app/Models/HoangPhi/VietnamMap/ (Province, District, Ward).
  • Artisan Commands: php artisan list (check vietnam-map: commands).

Implementation Patterns

Core Workflows

  1. Data Retrieval:

    • Hierarchical Queries:
      // Get all wards in a district
      $wards = District::find($districtId)->wards;
      
    • Eager Loading:
      $provinces = Province::with(['districts.wards'])->get();
      
  2. Customizing Data:

    • Add Columns: Extend migrations in database/migrations/{datetime}_create_vietnam_maps_table.php (e.g., population, postal_code).
    • Override Models: Publish and extend the models:
      php artisan vendor:publish --tag=vietnam-map-models
      
      Then modify app/Models/HoangPhi/VietnamMap/Province.php (e.g., add scopes):
      public function scopeInSouthernRegion($query) {
          return $query->whereIn('name', ['Ho Chi Minh', 'Binh Duong', 'Dong Nai']);
      }
      
  3. API Integration:

    • Laravel API Resources:
      php artisan make:resource ProvinceResource
      
      // app/Http/Resources/ProvinceResource.php
      public function toArray($request) {
          return [
              'id' => $this->gso_id,
              'name' => $this->name,
              'districts' => DistrictResource::collection($this->districts),
          ];
      }
      
  4. Frontend Integration:

    • Blade Templates:
      @foreach($provinces as $province)
          <select name="province">
              <option value="{{ $province->gso_id }}">{{ $province->name }}</option>
          </select>
          @foreach($province->districts as $district)
              <option value="{{ $district->gso_id }}">-- {{ $district->name }}</option>
          @endforeach
      @endforeach
      
    • Dynamic Selects with JavaScript:
      // Fetch districts via AJAX when province changes
      $('#province').change(function() {
          $.get(`/api/provinces/${this.value}/districts`, function(districts) {
              $('#district').html(districts.map(d => `<option value="${d.id}">${d.name}</option>`).join(''));
          });
      });
      
  5. Validation:

    • Use the gso_id for validation (e.g., in Laravel Forms):
      use HoangPhi\VietnamMap\Rules\ValidProvince;
      
      $request->validate([
          'province_id' => ['required', new ValidProvince],
      ]);
      

Gotchas and Tips

Pitfalls

  1. Migration Conflicts:

    • If you customize column names, ensure the gso_id (General Statistics Office ID) remains unique and matches the original dataset. Avoid renaming it to something ambiguous like id.
    • Fix: Backup your database before running migrations if extending the schema.
  2. Data Overwrites:

    • The vietnam-map:install command drops and recreates tables by default. Use --force carefully in production.
    • Tip: For updates, use --no-drop (if available) or manually handle data merges.
  3. Performance with Large Datasets:

    • Eager loading (with()) is critical for nested queries (e.g., provinces.districts.wards). Avoid N+1 queries:
      // Bad: N+1 query
      foreach (Province::all() as $province) {
          $province->districts; // Loads districts one by one
      }
      // Good: Eager load
      Province::with('districts')->get();
      
  4. Model Binding Issues:

    • The package uses gso_id as the primary key for Provinces/Districts/Wards. If you override the key, ensure your routes and bindings align:
      // In routes/web.php
      Route::get('/provinces/{province:gso_id}', ...);
      

Debugging

  1. Verify Data Integrity:

    • Check for missing records:
      $missingDistricts = District::whereNull('province_id')->get();
      
    • Use Tinker to inspect relationships:
      php artisan tinker
      >>> $province = \HoangPhi\VietnamMap\Models\Province::find(1);
      >>> $province->districts->count();
      
  2. Log Queries:

    • Enable Laravel query logging in config/logging.php or use a package like barryvdh/laravel-debugbar to inspect SQL.

Tips

  1. Extend the Dataset:

    • Add custom fields (e.g., latitude, longitude) via migrations:
      Schema::table('vietnam_maps_districts', function (Blueprint $table) {
          $table->decimal('latitude', 10, 8)->nullable();
          $table->decimal('longitude', 11, 8)->nullable();
      });
      
    • Populate with external APIs (e.g., Google Maps Geocoding).
  2. Caching:

    • Cache hierarchical data to reduce database load:
      $provinces = Cache::remember('vietnam.provinces', now()->addHours(1), function() {
          return Province::with('districts.wards')->get();
      });
      
  3. Localization:

    • Store translated names in a localizations table and use Laravel’s localization features:
      // Example: Add a `localized_names` JSON column
      $province->localized_names = ['en' => 'Hanoi', 'vi' => 'Hà Nội'];
      
  4. Testing:

    • Use factory-like seeding for tests:
      // database/seeds/VietnamMapsSeeder.php
      public function run() {
          Province::factory()->count(10)->create()->each(function ($province) {
              $province->districts()->saveMany(District::factory()->count(rand(5, 20))->make());
          });
      }
      
    • Mock the models in unit tests:
      $province = Mockery::mock(\HoangPhi\VietnamMap\Models\Province::class);
      $province->shouldReceive('districts')->andReturn(collect([$districtMock]));
      
  5. Custom Commands:

    • Extend the package’s commands (e.g., add a vietnam-map:update command to pull latest data):
      // app/Console/Commands/UpdateVietnamMaps.php
      public function handle() {
          $this->call('vietnam-map:install', ['--force' => true]);
      }
      
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.
ilhamsyabani/laravel-volt-starter
thethunderturner/filament-latex
ghostcompiler/laravel-querybuilder
webrek/laravel-telescope-mongodb
anousss007/blatui
zatona-eg/zatona-eg-api
cocosmos/filament-sticky-save-bar
patrickbussmann/oauth2-apple
3brs/enterprise-security-bundle
anousss007/vigilance
supportpal/eloquent-model
ardenexal/fhir-models
laravel-at/laravel-image-sanitize
romalytar/yammi-audit-log-laravel
ardenexal/fhir-validation
arshaviras/weather-widget
laravel-chronicle/core
sunchayn/nimbus
daikazu/eloquent-salesforce-objects
unseen-codes/chat