Skip to main content

Overview

The Tag model represents tags that can be applied to blog posts. Tags provide flexible labeling and help users discover related content. Posts can have multiple tags through a many-to-many relationship. Namespace: App\Models\Tag File: app/Models/Tag.php:7

Properties

Fillable attributes

name
string
required
The name of the tag (e.g., “php”, “tutorial”, “beginner”)

Relationships

posts()

Many-to-many relationship with the Post model. Returns: BelongsToMany<Post> Pivot table: post_tag
// Get all posts with a specific tag
$tag = Tag::where('name', 'laravel')->first();
$posts = $tag->posts;

// Get tags with post count
$popularTags = Tag::withCount('posts')
    ->orderBy('posts_count', 'desc')
    ->take(10)
    ->get();

Usage examples

Creating tags

$tag = Tag::create(['name' => 'laravel']);

// Create multiple tags
$tags = collect(['php', 'mysql', 'livewire'])->map(function($name) {
    return Tag::firstOrCreate(['name' => $name]);
});

Tagging posts

$post = Post::find(1);

// Attach tags
$post->tags()->attach([1, 2, 3]);

// Sync tags (replaces existing)
$post->tags()->sync([1, 2]);

// Detach all tags
$post->tags()->detach();

Querying by tags

// Get all posts with a specific tag
$laravelPosts = Post::whereHas('tags', function($query) {
    $query->where('name', 'laravel');
})->get();

// Get posts with multiple tags (AND)
$posts = Post::whereHas('tags', function($query) {
    $query->where('name', 'laravel');
})->whereHas('tags', function($query) {
    $query->where('name', 'php');
})->get();

// Get posts with any of multiple tags (OR)
$posts = Post::whereHas('tags', function($query) {
    $query->whereIn('name', ['laravel', 'php', 'mysql']);
})->get();

Tag cloud

// Generate tag cloud with sizes based on usage
$tagCloud = Tag::withCount('posts')
    ->having('posts_count', '>', 0)
    ->orderBy('name')
    ->get()
    ->map(function($tag) {
        return [
            'name' => $tag->name,
            'count' => $tag->posts_count,
            'size' => min(3, ceil($tag->posts_count / 5)) // Size from 1-3
        ];
    });

Database schema

The tags table contains:
  • id - Primary key
  • name - Tag name (string)
  • created_at - Timestamp
  • updated_at - Timestamp
The pivot table post_tag contains:
  • post_id - Foreign key to posts
  • tag_id - Foreign key to tags

Best practices

Consider normalizing tag names to lowercase to prevent duplicates like “Laravel” and “laravel”. Implement this in a model accessor or when creating tags.
Use firstOrCreate() when adding tags to prevent duplicate tag creation from user input.

Post model

View Post model documentation

Blog feature

Learn about the blog feature

Build docs developers (and LLMs) love