Keeping the Latest Activity
Introduction
keepLatest() keeps the latest matching activity in the feed and removes earlier ones, including from log().
Replacing Earlier Activities
use App\Models\Order;
use Storyfeed\Facades\Story;
Story::for(Order::class)->verb('save')
->headline(':actor saved :object')
->keepLatest(); // Earlier saves of this order are removed from log() too.Publish as usual. The declaration applies wherever you publish this verb:
Storyfeed::activity()->by($request->user())->action('save', $order)->publish();Storyfeed::record(
verb: 'save',
object: $order,
actor: $request->user(),
);After several saves of the same order, the feed contains only the latest:
Activities for other objects and verbs remain.
Choosing Matching Roles
Replace the original save declaration with this one:
use App\Models\Order;
use Storyfeed\Facades\Story;
Story::for(Order::class)->verb('save')
->headline(':actor saved :object')
->keepLatest(per: ['object', 'actor']);The feed keeps each actor's latest save of each order. Pass one role name or an array to per; the verb is always part of the match. An activity replaces nothing if a matching role is empty. For example, an anonymous save has no recorded actor, so it replaces nothing under per: ['object', 'actor'].
Limiting the Time Window
Add a time window to that declaration:
use App\Models\Order;
use Storyfeed\Facades\Story;
Story::for(Order::class)->verb('save')
->headline(':actor saved :object')
->keepLatest(per: ['object', 'actor'], within: '10 minutes');Only matching activities within ten minutes of the new activity's published_at are considered. Older saves outside the window remain. within accepts a positive interval string or a DateInterval.
| Declaration | Matching Activities |
|---|---|
keepLatest() | same object and verb, without a time limit |
keepLatest(per: ['object', 'actor']) | same object, actor and verb |
keepLatest(within: '10 minutes') | same object and verb, within ten minutes |
| no declaration | every activity remains |
Deleting Superseded Activities
By default, superseded activities are soft-deleted. They leave the feed but remain in the activities table until pruning. To delete them permanently as they are superseded:
'keep_latest' => [
'delete' => 'force',
],| Value | Superseded Activities |
|---|---|
'soft' | soft-deleted; the default |
'force' | deleted |
Storyfeed keeps the latest published_at, regardless of arrival order. A backdated activity older than a matching one is stored as soft-deleted, or discarded under 'force'.
Comparing With Unique Stories
ShouldBeUnique keeps the first pending publication. keepLatest() replaces matching stored activities after publication.