relationship() method on the disk uploader.
First complete steps 1–5 of the Post gallery recipe:
models, policy, filename generator, GalleryRows and GalleryFields. Skip its
custom PostGallery page and Blade view. Both integrations use exactly the same
field configuration and map originals to related SQL rows.
The related gallery adapter can replace the recipe’s
GalleryRows implementation when you want package-owned row synchronization and
stale-edit detection. Preserve the native page transaction and acceptance hooks
described here.
What happens on save?
- Filament validates the form and stores temporary uploads.
- The page writes the Post’s permitted attributes and related gallery rows inside its database transaction. Gallery fields are not assigned to Post attributes.
- Native
RecordSavedhandling checks the saved references and accepts staged uploads after commit. Unlike a custom save page, these Resource pages do not need a manualcompleteMediaUploadsAfterSave()call. - Editing hydrates each gallery from its own collection and disk. Query scoping and the Post policy prevent opening another owner’s record.
$hasDatabaseTransactions = true is intentional on both pages. The mapper rejects
writes outside a transaction. This does not turn SQL and disk/S3 into one atomic
transaction. Keep the original recipe’s reference-aware retention policy and
test your queue/encoder settings separately.
1. Add the fields to the Resource
The standalone example includes a minimal table. An existing Resource can keep its table, routes, actions and other attributes. Preserve every application-specific policy and tenant scope when merging the example’s owner condition.app/Filament/Resources/PostResource.php
2. Save on create
Onlytitle is mass assigned. The authenticated owner comes from the server;
submitted user_id or post_id values are not accepted as authority.
app/Filament/Resources/PostResource/Pages/CreatePost.php
3. Restore and save on edit
The edit page exposes only the title and the gallery state needed by its form. It reloads and locks the Post, then checks the policy again before updating it. If you already override these methods, merge this mapping with your existing behavior. Other domain attributes still need their own explicit validated mapping.app/Filament/Resources/PostResource/Pages/EditPost.php
4. Keep the native list page
app/Filament/Resources/PostResource/Pages/ListPosts.php
PostResource::class in the application’s panel if it is not already
discovered. Do not register both this example and a second Resource for the same
route. The regular Post policy from the base recipe supplies viewAny, create
and owner-restricted update; no delete action is offered here.