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.

Mastering Pivot Data with FilamentPHP v3: Building a Relation Manager for a CRM Example
FilamentPHP: Accelerated Laravel Development

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.