Single-Record Resource by Argemiro Dias
CommunityA Filament plugin that solves the single-record resource pattern — resources that display exactly one record per authenticated user (e.g. "My Profile", "My Wallet", "My Settings") without an index page, and their arbitrarily nested child resources.
Author:
Argemiro Dias
Package health
Automated checks of this plugin's Composer package
15 checks
- Passed: GitHub Actions pinned to SHA
- Skipped: GitLab CI includes pinned to SHA
- Passed: Open security advisories
- Warning: Dependabot PR responsiveness — Stale Dependabot PRs: oldest general PR is 61 days old.
- Skipped: Renovate MR responsiveness
- Passed: Dependabot or Renovate configured
- Passed: Dependency update cooldown configured
- Passed: Provides a security policy
- Passed: Abandoned or archived — No consulted source marks the package abandoned (packagist, github).
- Passed: Commit and release recency — Active: last commit 61 days ago; last release 61 days ago.
-
Passed:
composer.lock not committed by library
—
composer.lockis absent from the released dist archive. - Passed: Dist archive is lean
-
Passed:
Current Laravel version supported
—
Package dependencies resolve together with current Laravel
13.0. -
Passed:
Current PHP version supported
—
Constraint
^8.2supports current PHP8.5. - Skipped: Current Symfony version supported
filament/
namespace. Review the source and install at your own risk. Found
malware or an unresolved security issue the author won't
address?
Report it
.
Documentation
- Compatibility
- Installation
- Core Concepts
- Step-by-Step Implementation
- Automatic Record Resolution (1:1 with authenticated user)
- Authorization Behavior
- Custom Resolution Strategies
- Nested Resources
- Screenshots
- Testing
- Changelog
- Contributing
- Security
- Credits
- License
This package implements the single-record resource pattern for Filament panels.
Instead of a list page (index) with many records, you open one resource that always resolves to one business record per authenticated user.
Common examples:
- My Profile
- My Wallet
- My Settings
- Current Subscription
#Compatibility
- Filament
^4.0 || ^5.0 - Laravel versions supported by the selected Filament major
#Installation
composer require coringawc/filament-single-record-resource
#Core Concepts
This package is based on two traits:
It also exposes an explicit contract interface, SingleRecordResolvableResource, for Resources that want first-class static-analysis support.
HasSingleRecordResource(Resource trait)
- Redirects index/navigation behavior to
view - Keeps sidebar navigation working without an
indexpage - Falls back to
viewauthorization on the resolved record whenviewAnyis denied - Exposes shared record resolution hooks on the Resource
- Helps nested resources resolve root URLs/slugs in single-record chains
HasSingleRecord(Page trait forViewRecordandEditRecord)
- Resolves the root single record automatically
- Supports custom resolution via builder or custom resolver method
- Prefers the Resource contract when available, while remaining compatible with legacy Resources that expose the same methods manually
- Normalizes breadcrumbs in deep nested resources
#Step-by-Step Implementation
#1. Create your resource as single-record root
In your Filament Resource, use HasSingleRecordResource and register only view (and optionally edit) pages.
<?php
namespace App\Filament\Resources\MyWallets;
use App\Filament\Resources\MyWallets\Pages\EditMyWallet;
use App\Filament\Resources\MyWallets\Pages\ViewMyWallet;
use CoringaWc\FilamentSingleRecordResource\Contracts\SingleRecordResolvableResource;
use CoringaWc\FilamentSingleRecordResource\Traits\HasSingleRecordResource;
use Filament\Resources\Resource;
class MyWalletResource extends Resource implements SingleRecordResolvableResource
{
use HasSingleRecordResource;
public static function getPages(): array
{
return [
'view' => ViewMyWallet::route('/'),
'edit' => EditMyWallet::route('/edit'),
];
}
}
#2. Use HasSingleRecord in ViewRecord
<?php
namespace App\Filament\Resources\MyWallets\Pages;
use App\Filament\Resources\MyWallets\MyWalletResource;
use CoringaWc\FilamentSingleRecordResource\Traits\HasSingleRecord;
use Filament\Resources\Pages\ViewRecord;
class ViewMyWallet extends ViewRecord
{
use HasSingleRecord;
protected static string $resource = MyWalletResource::class;
}
#3. Optional: also use HasSingleRecord in EditRecord
Yes, this package supports EditRecord too.
<?php
namespace App\Filament\Resources\MyWallets\Pages;
use App\Filament\Resources\MyWallets\MyWalletResource;
use CoringaWc\FilamentSingleRecordResource\Traits\HasSingleRecord;
use Filament\Resources\Pages\EditRecord;
class EditMyWallet extends EditRecord
{
use HasSingleRecord;
protected static string $resource = MyWalletResource::class;
}
#Automatic Record Resolution (1:1 with authenticated user)
By default, HasSingleRecord calls a builder that applies whereBelongsTo(Filament::auth()->user()).
In practice, this works automatically when your resource model has a belongsTo(User::class) relation that points to the authenticated Filament user.
Typical 1:1 setup:
User hasOne WalletWallet belongsTo User
Example model relationships:
// App\Models\User
public function wallet(): HasOne
{
return $this->hasOne(Wallet::class);
}
// App\Models\Wallet
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
With this, your single-record root page resolves the wallet for the logged-in user automatically.
For explicit static-analysis support, implement SingleRecordResolvableResource on Resources using HasSingleRecordResource. The package still accepts legacy Resources that define the same methods manually, but the interface is now the recommended public contract.
#Authorization Behavior
Filament normally uses viewAny() to decide whether a Resource can register navigation and be accessed at the Resource level.
For a root single-record resource, that default is too strict because there is no collection UX. This package now treats the Resource as accessible when:
viewAny()is allowed, orviewAny()is denied butview()is allowed for the resolved single record
This means a policy can intentionally deny listing while still allowing the user to open their own single record.
#Custom Resolution Strategies
If your rule is not a simple belongsTo(user), prefer overriding one of the methods below on the Resource so authorization and page loading stay aligned.
#A) Customize builder on the Resource (resolveSingleRecordBuilder)
public static function resolveSingleRecordBuilder(Builder $query): Builder
{
return parent::resolveSingleRecordBuilder($query)
->where('active', true);
}
#B) Full custom resolver on the Resource (resolveSingleRecord)
Use this when you need firstOrCreate, tenant logic, or complex business rules.
public static function resolveSingleRecord(): ?Model
{
/** @var \App\Models\User|null $user */
$user = filament()->auth()->user();
if ($user === null) {
return null;
}
return $user->wallet()->firstOrCreate([]);
}
#C) Optional page-specific override
If a specific ViewRecord/EditRecord page truly needs different resolution behavior than the Resource, you can still override the page methods:
protected function resolveSingleRecordBuilder(Builder $query): Builder
{
return parent::resolveSingleRecordBuilder($query)
->where('active', true);
}
#Nested Resources
For nested chains (for example MyWallet -> Companies -> Products):
- Keep
HasSingleRecordResourceon resources that follow the single-record flow - Keep
HasSingleRecordin deepViewRecord/EditRecordpages - If removing parent IDs from URLs, enforce strict query scoping in your models/pages
- Prefer implementing
SingleRecordResolvableResourceon Resources usingHasSingleRecordResourceso static analysis can understand the contract explicitly
This package also helps preserve breadcrumb consistency in deep nested routes.
#Screenshots
#MyWallet (Root Single Resource)

#Deep Nested Resource (MyWallet -> Companies -> Products)

#Testing
Run tests:
composer test
The package CI validates the plugin in two scenarios:
- Filament 4 latest stable in major
- Filament 5 latest stable in major
#Changelog
Please see CHANGELOG for details.
#Contributing
Please see CONTRIBUTING.
#Security
Please review our security policy.
#Credits
#License
The MIT License (MIT). See LICENSE.md.
Featured Plugins
A selection of plugins curated by the Filament team
Blueprint
Filament Blueprint is a premium Laravel Boost extension that helps AI agents produce accurate, detailed implementation plans and security reports for Filament apps.
Filament
Advanced Tables (formerly Filter Sets)
Supercharge your tables with powerful features like user-customizable views, quick filters, multi-column sorting, advanced table searching, convenient view management, and more. Compatible with Resource Panel Tables, Relation Managers, Table Widgets, and Table Builder!
Kenneth Sese
Spotlight Pro
Browse your Filament Panel with ease. Filament Spotlight Pro adds a Spotlight like Command Palette to your Filament Panel.
Dennis Koch