Composing a Coherent Activity
Before recording a new kind of activity, list its fields and check that they describe what happened.
Composing an Activity
:actor · :verb · :object · :targetFill in the values you plan to record, using — for empty fields. Check that they explain the event before writing its headline.
Recording an Accepted Invitation
inviter · joined · invitee · — incoherent
invitee · joined · invitee · — incoherent
invitee · accepted · invitation · project coherent| Composition | Meaning |
|---|---|
| Inviter · joined · invitee · — | The inviter sent the invitation earlier but did not act in this event. |
| Invitee · joined · invitee · — | The invitee appears as both actor and object, without identifying what they joined. |
| Invitee · accepted · invitation · project | Identifies who accepted, what they accepted, and which project it was for. |
Each field should identify someone or something involved in the event. The same entity may fill more than one role: someone editing their own profile is both actor and object.
Record the activity where your application accepts the invitation:
Storyfeed::activity()
->by($request->user())
->action('accept', $invitation)
->to($invitation->project)
->publish();Storyfeed::record(
verb: 'accept',
object: $invitation,
actor: $request->user(),
target: $invitation->project,
);use App\Models\Invitation;
use Storyfeed\Facades\Story;
Story::for(Invitation::class)->verb('accept')
->headline(':actor accepted :object to :target');Checking for Missing Roles
user · moved · document · folder BThis records the move but omits the document's original folder. Decide whether the event needs that detail; its omission does not make the other fields incorrect.
Check the stored values independently of the headline, since headline definitions can change later.
Checking Multiple Activities
Three autosaves recorded as separate revisions may each describe a valid event but produce repetitive activities. See Choosing When to Publish for where to publish and Repeating Activities for keeping only the latest.
Finding Unfilled Tokens
user · archived · document · — coherent — nothing was aimed atuse App\Models\Document;
use Storyfeed\Facades\Story;
Story::for(Document::class)->verb('archive')
->headline(':actor archived :object from :target'); // Nothing fills :target.The fields describe the event, but the headline includes an empty target. It displays a fallback where the target's name would be.