'decimal:7', 'longitude' => 'decimal:7', 'wikipedia_cached_at' => 'datetime', ]; /** * Get the route key for the model. */ public function getRouteKeyName(): string { return 'slug'; } /** * Boot the model and set up event listeners */ protected static function boot() { parent::boot(); static::creating(function ($city) { if (empty($city->slug)) { $city->slug = static::generateUniqueSlug($city->name); } }); static::updating(function ($city) { if ($city->isDirty('name') && empty($city->slug)) { $city->slug = static::generateUniqueSlug($city->name); } }); } /** * Generate a unique slug from city name */ protected static function generateUniqueSlug(string $name): string { $slug = Str::slug($name); $originalSlug = $slug; $count = 1; while (static::where('slug', $slug)->exists()) { $slug = $originalSlug . '-' . $count; $count++; } return $slug; } /** * Get all attractions for this city */ public function attractions(): HasMany { return $this->hasMany(Attraction::class); } /** * Get all trips that include this city */ public function trips(): BelongsToMany { return $this->belongsToMany(Trip::class, 'city_trip') ->withPivot('order') ->withTimestamps() ->orderByPivot('order'); } /** * Get users who favorited this city */ public function favoritedBy(): BelongsToMany { return $this->belongsToMany(User::class, 'favorites') ->withTimestamps(); } }