Laravel Filament: How to save data to related model
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Laravel Filament: Mastering Nested Data Saving in Relationships
As developers working with complex data structures in Laravel, managing relationships—especially when building admin interfaces with tools like Filament—often presents unique challenges. When you have a primary model (like Employee) related to secondary models (like Detail), structuring the form to allow users to interact with both sets of data and correctly persist changes across these relationships requires a nuanced approach.
This post addresses a common hurdle: how to save data from a related model (Detail) when editing the parent model (Employee) within a Filament Resource.
The Pitfall of Simple Dot Notation in Forms
You encountered an issue when attempting to use dot notation directly in your Filament schema, such as TextInput::make('detail.email'). While dot notation is fantastic for accessing nested data in Blade views or Eloquent queries, simply defining a field this way within a standard form context often doesn't automatically trigger the necessary Eloquent saving mechanism required by Filament or Laravel’s request cycle to create or update the related model instance.
The problem isn't usually with the syntax itself, but with how you instruct Filament/Eloquent to handle the creation or updating of that specific relationship during the save operation. To successfully save related data, we must explicitly manage the relationship lifecycle.
The Correct Approach: Managing Relationships in Filament
Instead of trying to force dot notation for saving, the best practice is to leverage Filament's relationship features, which guide you on how to interact with related records. For handling one-to-one or one-to-many relationships, we typically handle the creation/update of the related model within the resource's form() method or by using dedicated components.
Step 1: Define the Relationship Correctly
Ensure your Eloquent models are correctly set up with proper constraints and relationships. For instance, in your Employee model, you would have a hasOne or hasMany relationship pointing to the Detail model. Understanding these underlying relationships is crucial; Laravel’s Eloquent structure forms the bedrock for any Filament interaction, as discussed extensively in guides on laravelcompany.com.
Step 2: Implementing Nested Saving with Components
For complex nested data, especially when dealing with one-to-one relationships where you are editing a set of details, manually mapping fields is often clearer than relying solely on dot notation for saving. You can use Filament components to manage the related record directly.
Here is a conceptual example of how you might structure your EmployeeResource to handle the Detail data:
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
class EmployeeResource extends Resource
{
protected static ?string $resource = 'employees';
public static function form(Form $form): Form
{
return $form
->schema([
// Fields for the main Employee model
Forms\Components\TextInput::make('name'),
Forms\Components\TextInput::make('employee_id'),
// Container for related details
Forms\Components\Section::make('Employee Details')
->schema([
Forms\Components\TextInput::make('detail_email')
->label('Email Address')
->required(),
Forms\Components\TextInput::make('detail_mobile')
->label('Mobile Number')
->required(),
]),
]);
}
public static function save(array $data): bool
{
// 1. Save the main Employee model first (if applicable)
$employee = $this->model;
$employee->fill($data);
$employee->save();
// 2. Handle the related Detail model separately if it was submitted directly,
// or ensure the data structure allows for it to be saved via relationship management.
// If you were using a separate Detail Resource or nested form fields:
if (isset($data['detail_email'])) {
$employee->detail()->updateOrCreate(
['employee_id' => $employee->id], // Assuming foreign key exists
[
'email' => $data['detail_email'],
'mobile' => $data['detail_mobile'],
]
);
}
return true;
}
}
Best Practice: Using Actions for Complex Saves
For operations that involve creating or updating related records, relying solely on the standard form() structure can become cumbersome. A more robust approach in Filament is often to use Actions or Sub-Forms to manage the persistence logic cleanly. If you are managing the creation of a new Detail record alongside the Employee update, consider using a dedicated Action to handle the transaction:
use Filament\Actions\Action;
// Inside your Resource class...
public static function getActions(): array
{
return [
Action::make('save_details')
->label('Save Employee Details')
->action(function (array $data) {
$employee = static::getModel()
->find($data['employee_id']);
if ($employee) {
$employee->detail()->updateOrCreate(
['employee_id' => $employee->id],
[
'email' => $data['detail_email'],
'mobile' => $data['detail_mobile'],
]
);
}
}),
];
}
Conclusion
The key takeaway is that while dot notation is useful for querying data, saving related Eloquent models within a Filament form requires explicit instruction on the persistence layer. Do not rely on simple schema nesting for complex save operations. Instead, focus on structuring your forms to collect all necessary primary and relational data, and then use the save() method or custom Actions to execute the appropriate Eloquent logic for creating, updating, or associating related models. This separation ensures that your application remains clean, maintainable, and adheres to solid Laravel principles, making complex data management straightforward, much like adhering to good design patterns seen throughout laravelcompany.com.