Skip to main content

Overview

The Album model manages photo albums in LaraCMS. It supports media attachments, automatic slug generation, and relationships with photos. Albums are accessible via slugs for SEO-friendly URLs. Namespace: App\Models\Album Extends: Illuminate\Database\Eloquent\Model Implements: Spatie\MediaLibrary\HasMedia Traits:
  • InteractsWithMedia - Spatie Media Library integration

Properties

Table Name

protected $table = 'album';

Fillable Attributes

album_name
string
required
The name of the album
slug
string
URL-friendly version of the album name (auto-generated)
category
string
Category or type of the album
description
text
Detailed description of the album

Relationships

photos()

Type: belongsToMany Related Model: App\Models\Photo Pivot Table: album_photo Description: Returns all photos that belong to this album. An album can contain multiple photos, and photos can belong to multiple albums.
public function photos()
{
    return $this->belongsToMany(Photo::class, 'album_photo');
}
Example:
$album = Album::find(1);
$photos = $album->photos;

foreach ($photos as $photo) {
    echo $photo->title;
}

Methods

boot()

Returns: void Description: Boot method that automatically generates a slug from the album name when creating a new album.
protected static function boot()
{
    parent::boot();
    static::creating(function ($album) {
        // Only generate slug if album_name is set
        if ($album->album_name) {
            $album->slug = Str::slug($album->album_name);
        }
    });
}
Example:
$album = Album::create([
    'album_name' => 'Summer Vacation 2024',
    'category' => 'Travel',
]);

// Slug is automatically set to: 'summer-vacation-2024'
echo $album->slug;

getRouteKeyName()

Returns: string Description: Configures Laravel to use the ‘slug’ field instead of ‘id’ for route model binding, enabling SEO-friendly URLs.
public function getRouteKeyName()
{
    return 'slug';
}
Example:
// Route definition
Route::get('/albums/{album}', [AlbumController::class, 'show']);

// URL: /albums/summer-vacation-2024 (instead of /albums/1)
// In controller:
public function show(Album $album) {
    // $album is automatically loaded by slug
}

registerMediaConversions()

Parameters:
  • $media - Spatie\MediaLibrary\MediaCollections\Models\Media|null
Returns: void Description: Defines image conversions for album media. Creates a ‘preview’ conversion that fits images to 300x300 pixels.
public function registerMediaConversions(?Media $media = null): void
{
    $this
        ->addMediaConversion('preview')
        ->fit(Fit::Contain, 300, 300)
        ->nonQueued();
}

Usage Examples

Creating an Album

use App\Models\Album;

$album = Album::create([
    'album_name' => 'Wedding Photography',
    'category' => 'Events',
    'description' => 'Beautiful moments from the wedding ceremony',
]);

// Slug is automatically generated: 'wedding-photography'

Adding Media to Album

$album = Album::find(1);

// Add media file
$album->addMedia($request->file('cover_image'))
    ->toMediaCollection();

// Get all media
$media = $album->getMedia();

// Get first media URL
$coverUrl = $album->getFirstMediaUrl();

// Get preview conversion
$previewUrl = $album->getFirstMediaUrl('default', 'preview');

Working with Photos

$album = Album::find(1);

// Attach photos to album
$album->photos()->attach([1, 2, 3]);

// Attach single photo
$album->photos()->attach($photoId);

// Sync photos (replace all existing)
$album->photos()->sync([1, 2, 3, 4, 5]);

// Detach photo
$album->photos()->detach($photoId);

// Get photo count
$photoCount = $album->photos()->count();

Finding Albums

// Find by slug
$album = Album::where('slug', 'wedding-photography')->first();

// Using route model binding (automatically uses slug)
// Route: /albums/{album}
// URL: /albums/wedding-photography

// Find by category
$eventAlbums = Album::where('category', 'Events')->get();

// Search by name
$albums = Album::where('album_name', 'like', '%Wedding%')->get();

Retrieving Albums with Photos

// Eager load photos
$albums = Album::with('photos')->get();

// Load photos with media
$album = Album::with('photos.media')->find(1);

// Get albums that have photos
$albumsWithPhotos = Album::has('photos')->get();

// Get albums with photo count
$albums = Album::withCount('photos')->get();

foreach ($albums as $album) {
    echo "{$album->album_name} has {$album->photos_count} photos";
}

Updating Albums

$album = Album::find(1);

$album->update([
    'album_name' => 'Updated Album Name',
    'description' => 'Updated description',
]);

// Note: Slug is NOT automatically updated on updates
// To update slug manually:
$album->slug = Str::slug($album->album_name);
$album->save();

Deleting Albums

$album = Album::find(1);

// This will remove the album but NOT the photos
// Photos can still exist in other albums
$album->delete();

// To also detach all photos before deleting:
$album->photos()->detach();
$album->delete();

Database Schema

The album table includes:
  • id - Primary key
  • album_name - Album name
  • slug - URL-friendly slug (unique)
  • category - Album category
  • description - Album description
  • created_at - Timestamp
  • updated_at - Timestamp

Pivot Tables

album_photo:
  • album_id - Foreign key to album table
  • photo_id - Foreign key to photos table
  • Photo - Photos in the album

Build docs developers (and LLMs) love