GluePear
GluePear

Reputation: 7725

Touching Eloquent model via polymorphic relationship

Laravel 5.7. I have two models, Foo and Content. Their relationship is polymorphic because Content can also be related to other models:

class Foo extends Model
{
    public function contents()
    {
        return $this->morphToMany('App\Content');
    }
}

class Content extends Model
{
    use LastModified;

    public function foos()
    {
        return $this->morphedByMany('App\Foo');
    }
}

I want to touch the Foo model whenever the Content model is updated. So I use a LastModified trait for the Content model:

trait LastModified
{
    protected static function bootLastModified()
    {
        static::updating(function ($model) {
            static::updateLastModified($model);
        });
    }

    protected static function updateLastModified($model)
    {
        $foos = $model->foos;
        if (count($foos) > 0) {
            foreach ($foos as $foo) {
                $foo->touch();
            }
        }
    }
}

My problem is that $model->foos returns the correct Foo models, but with the wrong ids. Instead of the Foo's own model id, each Foo has the id of the pivot table row. This means that the wrong Foo row is touched.

Upvotes: 0

Views: 1276

Answers (1)

Nicklas Kevin Frank
Nicklas Kevin Frank

Reputation: 6337

Laravel has built-in functionality for touching parent timestamps.

On the content model, you can add a property telling which relationships should be touched when the given model is updated.

The following should work:

class Content extends Model
{
    protected $touches = ['foos'];

    public function foos()
    {
        return $this->morphedByMany('App\Foo');
    }
}

Edit: Since you are using a static updated event you should manually call $model->touchOwners() from the static::updated

Upvotes: 2

Related Questions