belongsTo(Member::class); } protected static function booted() { static::created(fn (self $summary) => static::cascadeAttributes($summary)); static::updated(fn (self $summary) => static::cascadeAttributes($summary)); static::deleting(fn (self $summary) => static::cascadeAttributes($summary)); } /** * @todo extract to generic subsystem */ private static function cascadeAttributes(self $summary): void { static::maybeCascadeAttribute($summary, 'updated_at', 'member', 'updated_at'); } /** * @todo extract to generic subsystem */ private static function maybeCascadeAttribute( self $summary, string $sourceAttribute, string $relationship, string $targetAttribute ): void { $target = $summary->{$relationship} ?? null; if (is_null($target)) { return; } /** @var Model $target */ Assert::isAOf($target, Model::class); $target->withoutEvents(fn () => static::cascadeAttribute($summary, $target, $sourceAttribute, $targetAttribute)); } /** * @todo extract to generic subsystem */ private static function cascadeAttribute(self $summary, Model $target, string $sourceAttribute, string $targetAttribute): void { $target->update([ $targetAttribute => $summary->{$sourceAttribute}, 'timestamps' => false, ]); } }