Hook context
Read the user, current and saved values, and request information available inside a hook.
Ridu passes information about the current operation to each hook. This argument is usually named
ctx. Collection and global hooks receive one ridu.HookContext; field hooks receive a field
context and a separate value argument.
Read the document and signed-in user
Collection and global hooks receive ridu.HookContext.
Use it to read the signed-in user, inspect the previous document, or change values before a save:
| Value | What it contains |
|---|---|
Operation |
The create, duplicate, read, update, delete, publish, or unpublish operation |
Actor |
The authenticated document, or nil for an anonymous operation |
ActorCollection |
The auth collection that owns the signed-in user |
CollectionID / GlobalID |
The stable resource ID; only the matching one is set |
Data |
Values you can change before the document is saved |
Document |
The document being returned, once it is available |
Original |
The saved document before an update or delete |
Context |
Request cancellation and deadline; pass it to ctx.Local calls |
Local |
The local API for reading or writing related documents |
Error |
The original failure while AfterError runs |
Locale / AllLocales |
The locale view selected for this operation |
Values in Data use store.Value. Read a string with
StringValue() and write one with
store.String(...). Documents and values
explains the complete pattern, including missing values, nested data, and changes to a returned
document. For collection IDs, document IDs, and locales, read
Schema and identifiers.
Change stored values or response values
Before saving, update entries in ctx.Data. After checking that ctx.Actor is not nil, for
example, set ctx.Data["lastEditedBy"] = store.String(ctx.Actor.ID). Returning nil keeps those changes and
continues the operation. The hook returns only an error; it does not return a replacement document.
Assigning a new map to ctx.Data itself will not replace Ridu’s map.
After storage, ctx.Document contains the returned document. Changes to
ctx.Document.Values in AfterChange, AfterOperation, or AfterRead affect the response only;
they do not update the saved record. Use a before-save hook for a stored change.
ctx.Original contains the saved document before an update or delete. It is nil for a create,
and ctx.Document is unavailable before a result exists. General hooks on a list do not receive
a single result document; use AfterRead to work with each document.
ctx.Operation names the original operation. An AfterRead hook preparing a newly created post
still sees operation.Create, not operation.Read.
CollectionID and GlobalID are Ridu’s stable identifiers, not the slugs in your config.
Use Locale and AllLocales to understand the values supplied to this hook. Write hooks use
the write locale; AfterRead uses the response locale, which may include fallback text.
Work with a field context
A field hook receives ctx plus a separate operation.Value[T] for its
own value. The context contains read-only views:
ctx.Siblingscontains this field and other fields in the same object or row.ctx.Rootcontains the top-level fields.ctx.Priorcontains the previously saved version of the same object or row.
In a field transform, return operation.Replace(...) to change the field. Editing a map or slice read from these
views does not change the document. Unlike a collection hook’s Actor pointer, a field context
uses ctx.Actor.ID for the user ID; an empty ID means the request is anonymous.
See Using other field values for complete examples covering nested rows, previous values, translations, and related-document lookups.
Pass the user and locale to related operations
A collection or global hook’s ctx.Local is the ordinary local API. When a nested operation
should use the same user, pass Actor: ctx.Actor and ActorCollection: ctx.ActorCollection in
its options. Pass Locale: ctx.Locale when it should use the same content language. These
options are not filled in automatically; a nil actor makes an anonymous request.
Pass ctx.Context to share the active transaction and request cancellation. See
Save related documents together for
the complete audit-log example and rollback behavior.
The field context’s ctx.Local.FindByID reader already carries the user, auth collection, exact
locale, and transaction. It only supports reads; use a collection or global hook for related
writes.
Avoid triggering the same hook again
A local API call runs the target collection’s hooks too. If a posts hook writes an audit entry,
attach it to posts only; attaching it to the audit collection would make each log entry create
another log entry. Similarly, updating a post from its own AfterChange hook can start a loop.
Ridu rejects excessive recursion, but design the hook so it does not call itself. Change
ctx.Data before saving when the change belongs to the same document. Use a separate collection
when the hook creates a related record, and check what that collection’s hooks will do.
Calls made from AfterCommit use new transactions and can trigger hooks again. Keep notification
hooks focused on delivery instead of updating the same document after every save.
Read unsaved values during a live check
A .LiveValidate(...) callback receives operation.LiveValidationContext. It has the unsaved
form values and saved values for comparison, but no writable ctx.Data. Defaults and save hooks
have not run, and related lookups through ctx.Local are read-only.
See Live server validation for its context properties and lookup limits. These checks run separately from document and field hooks.