Merge pull request #17183 from filamentphp/fix/nested-resource-relation-manager-redirects

fix: Nested resource relation manager redirects
This commit is contained in:
Dan Harrin
2025-08-04 09:51:16 +01:00
committed by GitHub
4 changed files with 42 additions and 4 deletions
@@ -114,6 +114,19 @@ public static function getRelations(): array
Once a table and form have been defined for the relation manager, visit the [Edit](editing-records) or [View](viewing-records) page of your resource to see it in action.
### Customizing the relation manager's URL parameter
If you pass a key to the array returned from `getRelations()`, it will be used in the URL for that relation manager when switching been multiple relation managers. For example, you can pass `posts` to use `?relation=posts` in the URL instead of a numeric array index:
```php
public static function getRelations(): array
{
return [
'posts' => RelationManagers\PostsRelationManager::class,
];
}
```
### Read-only mode
Relation managers are usually displayed on either the Edit or View page of a resource. On the View page, Filament will automatically hide all actions that modify the relationship, such as create, edit, and delete. We call this "read-only mode", and it is there by default to preserve the read-only behavior of the View page. However, you can disable this behavior, by overriding the `isReadOnly()` method on the relation manager class to return `false` all the time:
+15
View File
@@ -65,3 +65,18 @@ public static function getParentResourceRegistration(): ?ParentResourceRegistrat
```
You can omit the calls to `relationship()` and `inverseRelationship()` if you want to use the default names.
## Registering a relation manager with the correct URL
When dealing with a nested resource that is listed by a relation manager, and the relation manager is amongst others on that page, you may notice that the URL to it is not correct when you redirect from the nested resource back to it. This is because each relation manager registered on a resource is assigned an integer, which is used to identify it in the URL when switching between multiple relation managers. For example, `?relation=0` might represent one relation manager in the URL, and `?relation=1` might represent another.
When redirecting from a nested resource back to a relation manager, Filament will assume that the relationship name is used to identify that relation manager in the URL. For example, if you have a nested `LessonResource` and a `LessonsRelationManager`, the relationship name is `lessons`, and should be used as the [URL parameter key](managing-relationships#customizing-the-relation-managers-url-parameter) for that relation manager when it is registered:
```php
public static function getRelations(): array
{
return [
'lessons' => LessonsRelationManager::class,
];
}
```
+12 -2
View File
@@ -392,8 +392,8 @@ The following code examples illustrate how field state may now return an enum in
```php
use App\Enums\Status;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput
;use Filament\Schemas\Components\Utilities\Get;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Utilities\Get;
Select::make('status')
->options(Status::class)
@@ -411,6 +411,16 @@ $data = $this->form->getState();
```
</Disclosure>
<Disclosure x-show="packages.includes('panels')">
<span slot="summary">URL parameter names have changed</span>
Filament v4 has renamed some of the URL parameters that are used on resource pages, to make them cleaner in the URL and easier to remember:
- `activeRelationManager` has been renamed to just `relation` on Edit / View resource pages.
To find out if you are using this parameter in your code, try searching for `'activeRelationManager' => ` (etc.) in your code, and looking for areas where you are using `::getUrl()` or another method of generating a URL with a parameter.
</Disclosure>
<Disclosure x-show="packages.includes('panels')">
<span slot="summary">Automatic tenancy global scoping and association</span>
@@ -81,7 +81,7 @@ trait CanGenerateUrls
if ($parentResource::hasPage('view')) {
return $parentResource::getUrl('view', [
'activeRelationManager' => $parentResourceRegistration->getRelationshipName(),
'relation' => $parentResourceRegistration->getRelationshipName(),
...$parameters,
'record' => $record,
], $isAbsolute, $panel, $tenant, $shouldGuessMissingParameters);
@@ -89,7 +89,7 @@ trait CanGenerateUrls
if ($parentResource::hasPage('edit')) {
return $parentResource::getUrl('edit', [
'activeRelationManager' => $parentResourceRegistration->getRelationshipName(),
'relation' => $parentResourceRegistration->getRelationshipName(),
...$parameters,
'record' => $record,
], $isAbsolute, $panel, $tenant, $shouldGuessMissingParameters);