Mastering Pivot Data with FilamentPHP v3: Building a Relation Manager for a CRM Example
Explore how "Mobilize," a CRM for churches, leverages FilamentPHP's Relation Managers to track congregants' skills. Learn to set up and manage relationships between profiles and skills, and handle pivot data effectively in this detailed guide.
Introduction
I'm developing Mobilize, a CRM designed specifically for churches. This CRM aims to keep track of the skills and talents that congregants are willing to donate to their faith communities. Managing these relationships between profiles (congregants) and skills within Mobilize is facilitated using Relation Managers in FilamentPHP.
Scenario Description
Our CRM manages the relationships between church members (profiles) and their skills. Efficiently managing this many-to-many relationship is crucial for our system's functionality, allowing us to effectively track and organize member skills.
Overview of Filament Relation Manager
A Relation Manager in FilamentPHP facilitates managing related data from a model. In Mobilize, setting up the ProfileResource to manage its relationship with the Skill via Relation Managers is straightforward, thanks to the clear documentation provided by Filament.
Step-by-Step Guide
1. Setting up the Relation Manager
To create a Relation Manager, you start by using the Artisan command provided by Filament:
php artisan make:filament-relation-manager SkillResource profiles full_name
This command generates a Relation Manager linked to the profiles
relationship within the SkillResource
. Once created, you can define the table's columns and actions within this manager.
Accessing Data in Table Actions
The challenge often arises when trying to directly access the profile_id
in table actions, as this identifier isn't directly available due to the context of the action. We have a pivot table named profile_skill
that contains the primary keys for profile_id
and skill_id
. In order to access the profile_id
or other model attributes during these actions, what you can utilize is the $record
parameter, which is injected automatically by the FilamentPHP framework. There are several places in the documentation that mention the existence of the $record parameter, but there doesn't seem to be a single place that explains it or its usage. You can read about it in the Advanced Forms documentation, but that doesn't explain its use in a FilamentPHP Table Action.
The most you get from the documentation is this line,
All methods on the action accept callback functions, where you can access the current table $record
that was clicked.
This variable represents the row data, and in this specific scenario, $record
is an instance of the Profile
model. This setup allows you to access all attributes of the Profile model. Leveraging $record
effectively enables the passage of relevant data to Filament's packages and functions.
Here’s an example of how the pivot table profile_skill
can be defined:
Schema::create('profile_skill', function (Blueprint $table) {
$table->bigInteger('profile_id')->unsigned();
$table->bigInteger('skill_id')->unsigned();
$table->timestamps(); // This shorthand adds both created_at and updated_at
});
This example of the pivot table includes both profile_id
and skill_id
as unsigned big integers and uses the shorthand timestamps()
method to add both created_at
and updated_at
columns.
Linking Back to Congregants
With access to the $record
for Table Actions, you can create a link back to the congregant via a closure:
Tables\Actions\Action::make('view-action')->label('View Profile')
->url(fn ($record) =>
ProfileResource::getUrl('view', ['record' => $record->id])),
This closure can be passed to the URL function, and when clicked, it routes the user back to the profile of the congregant.