njxqlus/filament-relation-manager-component
Installation:
composer require njxqlus/filament-relation-manager-component
Publish views (if customization is needed):
php artisan vendor:publish --provider="Njxqlus\FilamentRelationManager\ComponentServiceProvider"
First Use Case:
Register the component in a Filament resource's getPages() method:
use Njxqlus\FilamentRelationManager\Component;
public static function getPages(): array
{
return [
Component::make('posts', 'Posts'),
];
}
Basic Configuration:
Define relations in the model (e.g., Post):
public function comments()
{
return $this->hasMany(Comment::class);
}
Access the relation manager in the resource:
public static function getRelations(): array
{
return [
'comments',
];
}
Relation Management:
morphToMany, hasManyThrough).public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}
Register in resource:
public static function getRelations(): array
{
return [
'tags',
];
}
Customizing UI:
vendor:publish) to modify forms/tables.use Njxqlus\FilamentRelationManager\Component as BaseComponent;
class CustomRelationManager extends BaseComponent
{
protected static ?string $navigationIcon = 'heroicon-o-collection';
}
Integration with Filament Features:
Table or Form components for nested CRUD:
Component::make('comments')
->table(CommentTable::class)
->form(CommentForm::class),
relationManager() helper in resource actions:
public static function getTableActions(): array
{
return [
Tables\Actions\Action::make('manageRelations')
->action(function (Post $record) {
return RelationManager::make('posts', 'Posts')
->record($record)
->open();
}),
];
}
Dynamic Relations:
public static function getRelations(): array
{
return fn (Post $record) => $record->isPublished ? ['comments', 'tags'] : ['draftComments'];
}
Relation Not Found:
getRelations().php artisan tinker:
$post = Post::first();
$post->comments; // Verify relation works in Tinker.
Permission Issues:
canAccessRelationManager() in resources:
public static function canAccessRelationManager(): bool
{
return auth()->user()->can('manage-post-relations');
}
Performance:
getRecords() to avoid N+1 queries:
public static function getRecords(Table $table): array
{
return Post::with(['comments', 'tags'])->get();
}
View Publishing:
php artisan vendor:publish --tag="filament-relation-manager-views"
Log Relation Data:
Override getRelationData() in a custom component:
protected function getRelationData(string $relation): array
{
\Log::info("Fetching relation: {$relation}", ['data' => $this->record->$relation]);
return parent::getRelationData($relation);
}
Check Component Registration:
Verify the component is registered in getPages() and getRelations():
// Resource.php
public static function getPages(): array
{
return [
Component::make('posts', 'Posts'), // Must match relation name.
];
}
Custom Relation Managers: Extend the base component for reusable logic:
class MediaRelationManager extends Component
{
protected static string $model = Media::class;
protected static ?string $navigationGroup = 'Media';
}
Hooks: Use Filament’s hooks to modify behavior:
Filament::registerResourceHooks(function (ResourceHooks $resourceHooks) {
$resourceHooks->register('relation-manager.created', function (Post $record, string $relation) {
event(new RelationCreated($record, $relation));
});
});
Localization: Translate relation labels dynamically:
Component::make('comments')
->label(fn () => __("filament-relation-manager::relations.comments")),
How can I help you explore Laravel packages today?