Keeping Parent Models Up-to-Date: Laravel's $touches Property

Keeping Parent Models Up-to-Date: Laravel's $touches Property

In Laravel's Eloquent ORM, maintaining accurate timestamps across related models can be crucial for tracking changes and ensuring data consistency. The $touches property provides an elegant solution for automatically updating parent model timestamps when a related model is modified. Let's explore how this feature can streamline your data management process.

Understanding the $touches Property

The $touches property allows you to specify which parent relationships should have their updated_at timestamp updated when the current model is modified. This is particularly useful for belongsTo and belongsToMany relationships.

Basic Implementation

Let's consider a scenario where we have a Comment model that belongs to a Post model. We want the Post's updated_at timestamp to be updated whenever a related Comment is created, updated, or deleted.

Here's how you can implement this using the $touches property:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Comment extends Model
{
    protected $touches = ['post'];

    public function post(): BelongsTo
    {
        return $this->belongsTo(Post::class);
    }
}

With this configuration, any time a Comment is created, updated, or deleted, the updated_at timestamp of the associated Post will automatically be updated.

Practical Applications

1. Content Management Systems

In a CMS, you might want to track when a page was last modified, including changes to its components:

class PageComponent extends Model
{
    protected $touches = ['page'];

    public function page(): BelongsTo
    {
        return $this->belongsTo(Page::class);
    }
}

Now, whenever a component is updated, the parent page's timestamp will reflect this change.

2. E-commerce Product Reviews

For an e-commerce platform, you might want to update the product's timestamp when a new review is added:

class Review extends Model
{
    protected $touches = ['product'];

    public function product(): BelongsTo
    {
        return $this->belongsTo(Product::class);
    }
}

This ensures that products with recent reviews appear as recently updated.

3. Forum Threads and Replies

In a forum application, you can use $touches to keep thread timestamps current:

class Reply extends Model
{
    protected $touches = ['thread'];

    public function thread(): BelongsTo
    {
        return $this->belongsTo(Thread::class);
    }
}

This way, threads with recent replies will be easily identifiable.

Multiple Relationships

You can touch multiple parent relationships by adding more items to the $touches array:

class Comment extends Model
{
    protected $touches = ['post', 'user'];

    public function post(): BelongsTo
    {
        return $this->belongsTo(Post::class);
    }

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }
}

In this case, both the associated Post and User models will have their timestamps updated when the Comment is modified.

Touching Specific Timestamps

By default, $touches updates the updated_at timestamp. If you need to update a different timestamp, you can override the touchOwners method:

class Comment extends Model
{
    protected $touches = ['post'];

    public function touchOwners()
    {
        foreach ($this->touches as $relation) {
            $this->$relation()->touch('last_activity_at');
        }
    }
}

This will update a custom last_activity_at timestamp on the Post model instead of the default updated_at.

Real-World Scenario: Task Management System

Consider a task management system where tasks belong to projects. You want to ensure that whenever a task is updated, the project is marked as recently active:

class Task extends Model
{
    protected $touches = ['project'];

    public function project(): BelongsTo
    {
        return $this->belongsTo(Project::class);
    }
}

class Project extends Model
{
    public function tasks()
    {
        return $this->hasMany(Task::class);
    }
}

Now, in your application logic:

$task = Task::find(1);
$task->status = 'completed';
$task->save();

// The associated project's updated_at is automatically updated
echo $task->project->updated_at; // Shows the current timestamp

This simple implementation ensures that projects always reflect the latest activity from their tasks, which can be crucial for features like sorting projects by recent activity or triggering notifications for project updates.

The $touches property in Laravel provides a simple yet powerful way to maintain accurate timestamps across related models. By automatically updating parent model timestamps, it helps in keeping your data consistent and up-to-date, which is crucial for many real-world applications.

If this guide was helpful to you, subscribe to my daily newsletter and give me a follow on X/Twitter. It helps a lot!

Subscribe to Harris Raftopoulos

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe