Repeating Activities
When a verb repeats on the same object, keep every activity or call keepLatest() on the verb to keep only the latest.
Choosing a Storage Policy
Suppose an order is placed, confirmed, amended, and placed again. Choose whether to keep every activity or the latest for each verb:
| Request | Full Timeline | Latest Activity per Verb |
|---|---|---|
| first placement | append placed | replace placed |
| confirmation | append confirmed | replace confirmed |
| placed again after an amendment | append another placed | replace the earlier placed |
| visible rows afterward | first placement, confirmation, second placement | confirmation, second placement |
Keeping Every Occurrence
To keep the full timeline, publish the transition's verb in the controller on each request:
<?php
namespace App\Http\Controllers;
use App\Models\Order;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Storyfeed\Facades\Storyfeed;
class OrderTransitionController extends Controller
{
// Route::post('orders/{order}/{verb}', OrderTransitionController::class)
// ->whereIn('verb', ['place', 'confirm'])
public function __invoke(
Request $request,
Order $order,
string $verb,
): RedirectResponse {
$order->update(['status' => $verb]);
Storyfeed::activity()
->by($request->user())
->action($verb, $order)
->to($verb === 'place' ? $order->shop : null)
->publish();
return back();
}
}<?php
namespace App\Http\Controllers;
use App\Models\Order;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Storyfeed\Facades\Storyfeed;
class OrderTransitionController extends Controller
{
// Route::post('orders/{order}/{verb}', OrderTransitionController::class)
// ->whereIn('verb', ['place', 'confirm'])
public function __invoke(
Request $request,
Order $order,
string $verb,
): RedirectResponse {
$order->update(['status' => $verb]);
Storyfeed::record(
verb: $verb,
object: $order,
actor: $request->user(),
target: $verb === 'place' ? $order->shop : null,
);
return back();
}
}Retrieve the order's timeline in log mode:
use Storyfeed\Facades\Storyfeed;
$timeline = Storyfeed::feed()->involving($order)->log()->get();Keeping the Latest Occurrence
Call keepLatest() on each verb to replace its earlier activities. The controller publishes as before; the query below retrieves the feed in live mode:
use App\Models\Order;
use Storyfeed\Facades\Story;
Story::for(Order::class)->verb('place')
->headline(':actor placed :object with :target')
->keepLatest(); // removes earlier placements from every feed
Story::for(Order::class)->verb('confirm')
->headline(':actor confirmed :object')
->keepLatest();use Storyfeed\Facades\Storyfeed;
$latest = Storyfeed::feed()->involving($order)->live()->get();For this order, the feed keeps the latest activity for each verb.
Replaced activities disappear from every feed, including log(). Keep every activity if any page needs the full timeline.
See Keeping the Latest Activity for matching roles and time limits.