In Filament, you may need two-level nested resources, like Courses and Lessons inside of them. Sadly, Filament doesn't have this feature with convenient navigation out of the box yet. But in this tutorial, we will try to build nested resources functionality manually.
First, let's identify the problem we need to solve.
The Problem with Nested Resources
In short, our primary goal is to navigate to the children's records list (lessons) from the parent record (courses) list.
Also, we need to take care of quite a few things that happen next:
- After clicking "New lesson", Filament needs to automatically assign the "parent" course and redirect back to the correct course
- At all times, we must navigate inside the parent resource with URLs like
/courses/X/lessons
,/courses/X/lessons/Y
, etc.
For example, if we have the Edit form of courses/1/lessons/2
, we need to take care that, after submission, the user would be redirected to courses/1/lessons
- the list of lessons with the course ID 1.
In other words, we need to have the parent record data at any point when navigating the child record pages to assign the correct parent and redirect to the right pages. By default, your Filament LessonResource
will not know anything about the parent CourseResource
.
And, as we discovered, it's not easy to override the redirects in Filament. Some functions allow to specify the property values, but others are closed from direct modifications, especially POST requests after submitting the forms.
Now, let me show our solution. Remember, it's a bit experimental, and we're happy to improve it based on your feedback!
Step 1: DB Setup
In this project, we will use a hasMany
relationship.
Migrations
Schema::create('courses', function (Blueprint $table) { $table->id(); $table->string('name'); $table->timestamps();}); Schema::create('lessons', function (Blueprint $table) { $table->id(); $table->foreignId('course_id')->constrained(); $table->string('title'); $table->text('text'); $table->timestamps();});
Our Models define the relationship as hasMany
for Courses and belongsTo
for Lessons.
app/Models/Course.php
class Course extends Model{ use HasFactory; protected $fillable = [ 'name' ]; public function lessons(): HasMany { return $this->hasMany(Lesson::class); }}
app/Models/Lesson.php
class Lesson extends Model{ use HasFactory; protected $fillable = [ 'course_id', 'title', 'text', ]; public function course(): BelongsTo { return $this->belongsTo(Course::class); }}
That's it for our DB setup.
Step 2: Creating Two Filament Resources
For our Resource, we used the following commands:
php artisan make:filament-resource Course --generatephp artisan make:filament-resource Lesson --generate
This will create the Filament resources, generating the columns/inputs directly from the DB with the --generate
flag.
For now, at this stage, they are not nested yet.
We won't change anything in the CourseResource
for now.
app/Filament/Resources/CourseResource.php
class CourseResource extends Resource{ protected static ?string $model = Course::class; protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack'; public static function form(Form $form): Form { return $form ->schema([ Forms\Components\TextInput::make('name') ->required() ->maxLength(255), ]); } public static function table(Table $table): Table { return $table ->columns([ Tables\Columns\TextColumn::make('name') ->searchable(), Tables\Columns\TextColumn::make('created_at') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), Tables\Columns\TextColumn::make('updated_at') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), ]) ->filters([ // ]) ->actions([ Tables\Actions\EditAction::make(), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ Tables\Actions\DeleteBulkAction::make(), ]), ]); } public static function getRelations(): array { return [ // ]; } public static function getPages(): array { return [ 'index' => Pages\ListCourses::route('/'), 'create' => Pages\CreateCourse::route('/create'), 'edit' => Pages\EditCourse::route('/{record}/edit'), ]; }}
Next, in the LessonResource
, we did a few modifications:
- Remove the
course_id
field from the form (we will assign it automatically) - Remove the
course.name
column from the table (we will show only lessons of a specific course) - Disable the navigation (lessons will be accessible only through the "Courses" menu)
app/Filament/Resources/LessonResource.php
class LessonResource extends Resource{ protected static ?string $model = Lesson::class; protected static bool $shouldRegisterNavigation = false; public static function form(Form $form): Form { return $form ->schema([ // This field was generated, but we will not use it Forms\Components\Select::make('course_id') ->relationship('course', 'name') ->required(), Forms\Components\TextInput::make('title') ->required() ->maxLength(255), Forms\Components\Textarea::make('text') ->required() ->maxLength(65535) ->columnSpanFull(), ]); } public static function table(Table $table): Table { return $table ->columns([ // This column was generated, but we will not use it Tables\Columns\TextColumn::make('course.name') ->numeric() ->sortable(), Tables\Columns\TextColumn::make('title') ->searchable(), Tables\Columns\TextColumn::make('created_at') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), Tables\Columns\TextColumn::make('updated_at') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), ]) ->filters([ // ]) ->actions([ Tables\Actions\EditAction::make(), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ Tables\Actions\DeleteBulkAction::make(), ]), ]); } public static function getRelations(): array { return [ // ]; } public static function getPages(): array { return [ 'index' => Pages\ListLessons::route('/'), 'create' => Pages\CreateLesson::route('/create'), 'edit' => Pages\EditLesson::route('/{record}/edit'), ]; }}
Everything else generated is the same as the default Filament Resource (Create, Edit, List, etc.).
Step 3: Implementing the Nested Resource
Here comes the main part of this tutorial. We will have to modify quite a few files, so we will discuss each file and why we changed something. Let's start with creating a new Trait:
Here's what the Trait does:
- It will automatically resolve the parent resource's model and set it to
$this->parent
. - It will automatically apply a filter to the table query to only show records with the parent's ID.
- It will automatically generate breadcrumbs for the parent resource and the current resource. For example:
Courses > Filament Example - Nested resources > Lessons > List
- It will automatically resolve the relationship key like
course_id
for thelessons
table and set it to$this->relationshipKey
.
Notice: there's no Artisan command
make:trait
. You need to create that PHP file manually in your IDE.
app/Filament/Traits/HasParentResource.php
use Exception;use Illuminate\Database\Eloquent\Builder;use Illuminate\Database\Eloquent\Model;use Illuminate\Database\Eloquent\ModelNotFoundException; /** * @property string|null $relationshipKey Define custom relationship key (if it does not match the table name pattern). * @property string|null $pageNamePrefix Define custom child page name prefix (if it does not match the resource's slug). */trait HasParentResource{ public Model|int|string|null $parent = null; public function bootHasParentResource(): void { // Retrieve the parent resource's model. if ($parent = (request()->route('parent') ?? request()->input('parent'))) { $parentResource = $this->getParentResource(); $this->parent = $parentResource::resolveRecordRouteBinding($parent); if (!$this->parent) { throw new ModelNotFoundException(); } } } public static function getParentResource(): string { $parentResource = static::getResource()::$parentResource; if (!isset($parentResource)) { throw new Exception('Parent resource is not set for '.static::class); } return $parentResource; } protected function applyFiltersToTableQuery(Builder $query): Builder { // Apply any filters before the parent relationship key is applied. $query = parent::applyFiltersToTableQuery($query); return $query->where($this->getParentRelationshipKey(), $this->parent->getKey()); } public function getParentRelationshipKey(): string { // You can set Custom relationship key (if it does not match the table name pattern) via $relationshipKey property. // Otherwise, it will be auto-resolved. return $this->relationshipKey ?? $this->parent?->getForeignKey(); } public function getChildPageNamePrefix(): string { return $this->pageNamePrefix ?? (string) str(static::getResource()::getSlug()) ->replace('/', '.') ->afterLast('.'); } public function getBreadcrumbs(): array { $resource = static::getResource(); $parentResource = static::getParentResource(); $breadcrumbs = [ $parentResource::getUrl() => $parentResource::getBreadCrumb(), $parentResource::getRecordTitle($this->parent), $parentResource::getUrl(name: $this->getChildPageNamePrefix() . '.index', parameters: ['parent' => $this->parent]) => $resource::getBreadCrumb(), ]; if (isset($this->record)) { $breadcrumbs[] = $resource::getRecordTitle($this->record); } $breadcrumbs[] = $this->getBreadCrumb(); return $breadcrumbs; }}
Next, we will modify our CourseResource
to add a few things:
- Add record title for the parent resource to be used in breadcrumbs
- Add a link to each row for its nested resources
- Define routes for nested resource
app/Filament/Resources/CourseResource.php
use App\Filament\Resources\LessonResource\Pages\CreateLesson;use App\Filament\Resources\LessonResource\Pages\EditLesson;use App\Filament\Resources\LessonResource\Pages\ListLessons;use Filament\Facades\Filament;use Filament\Tables\Actions\Action;use Illuminate\Contracts\Support\Htmlable;use Illuminate\Database\Eloquent\Model;use Illuminate\Support\Facades\Route; // ... class CourseResource extends Resource{ // ... public static function getRecordTitle(?Model $record): string|null|Htmlable { return $record->name; } public static function table(Table $table): Table { return $table ->columns([ // ... ]) ->filters([ // ... ]) ->actions([ Tables\Actions\EditAction::make(), Action::make('Manage lessons') ->color('success') ->icon('heroicon-m-academic-cap') ->url( fn (Course $record): string => static::getUrl('lessons.index', [ 'parent' => $record->id, ]) ), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ Tables\Actions\DeleteBulkAction::make(), ]), ]); } public static function getRelations(): array { return [ // ]; } public static function getPages(): array { return [ 'index' => Pages\ListCourses::route('/'), 'create' => Pages\CreateCourse::route('/create'), 'edit' => Pages\EditCourse::route('/{record}/edit'), // Lessons 'lessons.index' => ListLessons::route('/{parent}/lessons'), 'lessons.create' => CreateLesson::route('/{parent}/lessons/create'), 'lessons.edit' => EditLesson::route('/{parent}/lessons/{record}/edit'), ]; }}
Now that our CourseResource
is ready, we can move on to our LessonResource
. We will do the following:
- Add record title for the child resource to be used in breadcrumbs
- ADd parent resource property
- Remove route definitions (they can stay, but it's not needed)
app/Filament/Resources/LessonResource.php
use Illuminate\Contracts\Support\Htmlable;use Illuminate\Database\Eloquent\Model; // ... class LessonResource extends Resource{ // ... public static string $parentResource = CourseResource::class; public static function getRecordTitle(?Model $record): string|null|Htmlable { return $record->title; } public static function table(Table $table): Table { return $table ->columns([ // ... ]) ->filters([ // ... ]) ->actions([ Tables\Actions\EditAction::make(), Tables\Actions\EditAction::make() ->url( fn (Pages\ListLessons $livewire, Model $record): string => static::$parentResource::getUrl('lessons.edit', [ 'record' => $record, 'parent' => $livewire->parent, ]) ), Tables\Actions\DeleteAction::make(), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ Tables\Actions\DeleteBulkAction::make(), ]), ]); } public static function getPages(): array { return [ 'index' => Pages\ListLessons::route('/'), 'create' => Pages\CreateLesson::route('/create'), 'edit' => Pages\EditLesson::route('/{record}/edit'), ]; }}
Now, we will start with our actual pages, starting with the ListLessons
page. We will do the following:
- Add the
HasParentResource
trait from above - Modify headers and create action to use the parent resource's URL
app/Filament/Resources/LessonResource/Pages/ListLessons.php
use App\Filament\Resources\CourseResource;use App\Filament\Traits\HasParentResource; // ... class ListLessons extends ListRecords{ use HasParentResource; protected static string $resource = LessonResource::class; protected function getHeaderActions(): array { return [ Actions\CreateAction::make(), Actions\CreateAction::make() ->url( fn (): string => static::getParentResource()::getUrl('lessons.create', [ 'parent' => $this->parent, ]) ), ]; }}
That's it for our ListLessons
page. Now, on the CreateLesson
page, we will do the following:
- Add the
HasParentResource
trait - Modify the redirect URL to use the parent resource's URL
- Mutate the form data to add the parent resource's ID
app/Filament/Resources/LessonResource/Pages/CreateLesson.php
use App\Filament\Resources\CourseResource;use App\Filament\Traits\HasParentResource; // ... class CreateLesson extends CreateRecord{ use HasParentResource; protected static string $resource = LessonResource::class; protected function getRedirectUrl(): string { return $this->previousUrl ?? static::getParentResource()::getUrl('lessons.index', [ 'parent' => $this->parent, ]); } // This can be moved to Trait, but we are keeping it here // to avoid confusion in case you mutate the data yourself protected function mutateFormDataBeforeCreate(array $data): array { // Set the parent relationship key to the parent resource's ID. $data[$this->getParentRelationshipKey()] = $this->parent->id; return $data; }}
And finally, on the EditLesson
page, we will do the following:
- Add the
HasParentResource
trait - Modify the redirect URL to use the parent resource's URL
- Configure the delete action redirects
app/Filament/Resources/LessonResource/Pages/EditLesson.php
use App\Filament\Resources\CourseResource;use App\Filament\Traits\HasParentResource; // ... class EditLesson extends EditRecord{ use HasParentResource; protected static string $resource = LessonResource::class; protected function getHeaderActions(): array { return [ Actions\DeleteAction::make(), ]; } protected function getRedirectUrl(): string { return $this->previousUrl ?? static::getParentResource()::getUrl('lessons.index', [ 'parent' => $this->parent, ]); } protected function configureDeleteAction(Actions\DeleteAction $action): void { $resource = static::getResource(); $action->authorize($resource::canDelete($this->getRecord())) ->successRedirectUrl(static::getParentResource()::getUrl('lessons.index', [ 'parent' => $this->parent, ])); }}
That's it! You should have working nested resources now! Here's how that looks in the admin panel:
This opens up a new page with the list of lessons for the selected course:
And here's the Edit form for the lesson:
Final Words
This is an experimental implementation of nested resources we came up with. We are considering adding this functionality to Filament core or releasing it as a plugin with a more robust solution, so any feedback is appreciated.
You can find the complete code for this tutorial on GitHub and all the changes in this commit
If you are looking for a multi-tenant example, you can find it in this GitHub Branch
Updates
The last revision of this tutorial was made on October 21, 2023. This includes a few updates:
- We have simplified the implementation to use less code and less complexity.
- We have improved the Trait to refer to the resource to get the parent resource.
- There was a removal of
$parentResource
on ourList
,Create
, andEdit
pages. - Removed custom URL resolving in our Parent resource
- Allowed Table actions to be moved back to the Resource file instead of the List file.
- Included a tenant code example link.
- This example has a fully working multi-tenancy support for Filament.
This came from our community member who made a PR Guilherme Saade, so big thanks to him!
If you want more Filament examples, you can find more real-life projects on our FilamentExamples.com.
Hello,
I'm using filament3 and looking for neseted resoure for my project.
I follow your tutorial, and when i click for Manage lessons it show me an error "Call to a member function uri() on null".
Hi, can you add more details on the error message itself? Not sure what would be wrong looking at this :)
Dear Mr.Modestas
I'm using filament v3 with laravel-modules, I create resoures under module.
I just download your code to test, it's work fine. So I'm not sure what happen with the code.
It error in this block code
public static function getUrl(string $name = 'index', array $parameters = [], bool $isAbsolute = true, ?string $panel = null, ?Model $tenant = null): string { $parameters['tenant'] ??= ($tenant ?? Filament::getTenant());
It seems that you are missing something in your setup. Check what might have gone wrong there and double check that you have all the routes defined on parent resource correctly
yes, i will try to check.
Thank you for your kindness. :)
Awesome!!! You're the best.
I have only one point, I am getting error when try to delete a lesson.
Filament\Resources\Pages\ListRecords::Filament\Resources\Pages{closure}(): Return value must be of type string, null returned
I just figured it out, now it work fine. In List Detail Record
// You can set the Custom relationship key (if it does not match the table name pattern) via the $relationshipKey property.
// Otherwise, it will be auto-resolved.
public function getParentRelationshipKey(): string { return $this->relationshipKey = "your_foreign_key"; }
In DetailResource
//Return string the same url you create in MasterResource
public static function getPluralModelLabel(): string { return __('details'); }
I hope it will help you!
This may also happen if your getRecordTitle function returns a null value. Remove the getRecordTitle function from your child resource to check if it solves the issue.
But that function technically accepts the
null
return. So it's a bit weird that it would be like this.Then again, maybe there is another issue with the code itself.
ps. This issue is in theory not existing with the latest code changes. Or at least, we did not encounter it nor we heard it happen again!
@Modestas https://github.com/filamentphp/filament/blob/8b1b5ee045d93f2423295e8110c8bff65739110a/packages/panels/src/Resources/Pages/ListRecords.php#L271 The anonymous function on this line returns a string, which restricts the getRecordTitle function to returning only strings. This is why it fails when the function returns null.
Oh, that makes sense! I probably overlooked that there. So then this function should return a string in any case. Will see what can be done (but honestly, I did not encounter this issue myself yet)
I think this is a bug on Filament side. The anonymous function should reflect the return types of the getRecordTitle function.
Hey guys, don't really know what I'm missing... after do everything you did in the guide, I'm getting a Route [filament.admin.resources.variations.index] not defined.
(I'm trying to replicate this with Services and Variations )
Hi, some code or debugging log would be awesome here!
But my main concern is that some routes are not registered correctly, or there is a method missing (like get url or breadcrumbs).
ps. We will be updating this article soon with improved and reduced code, you can already check that in repository!
Updated the article with new code! Please check if that solves your issue (new implementation and removed a lot of repeating code)
Cool, it's working now with the new code, thanks a lot!!
Hi again, for some reason it's not autopopulating the Parent Relationship Key even if I put manually the foreing key inside the getParentRelationshipKey function... any ideas ? https://flareapp.io/share/omwKOqWm
It seems that you forgot to add the
CreateResource
code to add the parent information:I have it there, but one weird thing I see is happening when I use the Create button when the table is Empty -> "emptyStateActions" and also is happening on delete button attached to each row, it's throwing an error "Filament\Resources\Pages\ListRecords::Filament\Resources\Pages{closure}(): Return value must be of type string, null returned" but when I use the delete button inside the record, it works fine...
I think you have some issues with the code on your end.
I just tries to add empty state action:
And it worked perfectly. Same with Delete button - it did work on both inside the table and inside the records.
Sadly, withou the actual code - there is not much I can help you as it is working just fine on our end...
don't know what's happening, I just put your code and this happened
https://flareapp.io/share/LPlK1bnm
Your namespace seems to be incorrect. If you don't know the exact one it should be - just remove yhe property type (pages\CreateVariation) and leave only the variable livewire
perfect, now is working! thank you!!
It is working fine for 2 levels of nested resources, but I'm encountering errors when attempting to add a third level of nested resources. Is it possible to make it work with 3 levels using your solutions?
Course 2. Lessons 3. Videos I'm receiving an error stating 'Missing required parameter for [Route: filament.admin.resources.lessons.videos.index] [URI: admin/lessons/{parent}/videos] [Missing parameter: parent].'
currently this is not possible. it was designed for 2 levels only, as 3 and more will require a lot more code modifications.
Sorry
Anyway, thank you for your hard work.
@Phanith Could you solve this for 3 levels?
@Nils Domin, I can create unlimited nested resources in filament using nested resource filament plugin by Guava.
additionally, I just simply modify its breadcrumbs function to match my need. but the plugin itself is great and working.
@Hani Ramadhan
I believe I'm on your same track. Would you mind sharing how you modified its breadcrumbs function?
Hi, I found that the filter is no longer working after use the nested resource. Tested out a while and found this block of code is the the problem:
Seems like it by pass the parent's method. Fixed the filter issue by adding parent call:
Good catch! Thank you, updating the example!
when i tried to add Tables\Actions\ViewAction::make(), to the table, i got the error message:
error: Filament\Resources\Pages\ListRecords::Filament\Resources\Pages{closure}(): Return value must be of type string, null returned
here is my resource code:
Hi, you need to add the HasParent trait to your view page too. We did not do that, but it should follow the exact same setup as we have with our List/Create/Edit pages
I don't have view page, but the problem was in this line
the correct in my case is title instead of name.
I got confused by viewQction then. But happy you solved it!
Thanks for your time
It also works for me, since I also generated the resource --simple
How to redirect to course lessons page after create in this example?
You can modify the
CreateXXX
redirect:And in there you can change where it redirects.
the question in another way: After i create a course i need to redirect to the manage lessons page
So you do the redirect in create course file, to this URL
It will need the id of the parent , how to get it?
$this->id ???
$this->record->id
Thanks
How can I use slideOver() on child pages?
This is not really related to the lesson here, but you need a very basic resource. That resource can't register create route in order for slideOver to work correctly. For example, on LessonResource:
Commenting out edit/create routes - makes the slide over work.
ps. Comment out the
url()
on your create button - it is not needed if you are using slideOversHi. i tried, but facing error like this. Trait "App\Filament\Traits\HasParentResource" not found
Filament\Resources\TaskResource\Pages\CreateTask.php : 11
this line 1-11
sorry solved, by adding
at first line
but i have another error.
This my Models
Can you add more details about the error you are facing? This can be many things (and probably is just a misconfiguration/syntax error somewhere)
You must have set the model in $parentResource and not the resource.
I'm getting SQLSTATE[HY000]: General error: 1364 Field 'course_id' doesn't have a default value
Please dump what the
getParentRelationshipKey
function returns. There is some kind of misconfiguration on your end as this is a module, and for whatever reason it takes course_id.Or in other words - the code you added does not tell me what you were trying to do, so I can't help effectively. Sorry!
Hi. It seems that my problem was here:
I copied that from the guide. I've now updated it to:
Do you have
parentResource
set on your child resources?Yes
I meant on the LessonResource, not on the lesson page. We have had a few updates to this article to make it more reliable
I do, this is my lesson resource:
Hmm, in that case - there is something off with Database setup. Sorry, really hard to help here. If you want us to better look at the issue - get in touch via email and provide the repository with your code - we can take a look and see what the problem might be :)
Symfony \ Component \Routing \ Exception \ RouteNotFoundException PHP 8.1.10 Laravel 10.21.0 Route [filament.app.resources.answers.index] not defined.
https://prnt.sc/FGvrbDZXG1SU
It seems like your route for answer should be filament.app.resources.questions.answers.index. You're missing the word question.
I followed this tutorial, while I used filament tenancy, where I can fix the route
Well, it's hard to say because I don't know what page you're visiting to get this error. Share the code for the page.
Visit Panel Tenancy https://prnt.sc/KiQu8qAFSi4f
github https://github.com/firmanms/filament2/tree/nested
You need to share the code of the page. There's a link that's pointing to the wrong route. I can't point it out unless I see your code. Your screenshot only shows that you have a route that's not pointed correctly.
i am trying to create a FAQ module
https://github.com/firmanms/filament2/blob/nested/database/migrations/2023_12_14_005730_create_questions_table.php
https://github.com/firmanms/filament2/blob/nested/database/migrations/2023_12_14_005739_create_answers_table.php
https://github.com/firmanms/filament2/blob/nested/app/Filament/App/Traits/HasParentResource.php
https://github.com/firmanms/filament2/blob/nested/app/Filament/App/Resources/QuestionResource.php
https://github.com/firmanms/filament2/blob/nested/app/Filament/App/Resources/AnswerResource.php
https://github.com/firmanms/filament2/blob/nested/app/Filament/App/Resources/AnswerResource/Pages/ListAnswers.php
https://github.com/firmanms/filament2/blob/nested/app/Filament/App/Resources/AnswerResource/Pages/CreateAnswer.php
https://github.com/firmanms/filament2/blob/nested/app/Filament/App/Resources/AnswerResource/Pages/EditAnswer.php
out of title post, i have question about crash style panel filament, any solution ? https://prnt.sc/f4HvWJM4A5Ex
I want to access data from the parent on the create page of the child. I couldn't find a way to get this parent id accessible in the childs resource. Does any of you have a solution for this.
It should be accessible via
$this->parent->id
if I'm not mistakenYes, that is the case if I want to access it on the page. However, I am not able to pass it to the resource, so I put information from the parent into a placeholder
Do you have a demo of this somewhere? I did something similar and it worked without too much issues
Within LessonResource:
This throws the following error: Using $this when not in object context
You are right, there is a bit of a different workaround there. Add this to your Lesson resource:
The static function
getParentInfo()
will load a model for you :)Thanks a lot for this solution. You have a small inconsistency in your code:
should be:
There is still something wrong when I also use a live() element in the resource. After a toggle, an error showed up on the return line: Attempt to read property "title" on null
Whoops! Sorry about the mistake, indeed I left it by accident (a bit of experimenting gone wrong haha).
Hmm, with the
->live()
it could for sure cause some issues. Here, I don't have a direct answer as this whole thing is pretty much a hack. So at this point, can't help you much as it needs investigation and probably more code modifications, sorry!After some thinkering around, I found a solution which is also kind of a hack. The Post request generated by the ->live(), also contains a snapshot, where the parent variable can be retrieved:
Awesome! This seems like a nice approach :)
Quick question... After setting up a Nested Resource as per your guide, my 'afterSave' actions on the on the Edit page stopped working. Same code works on non nested resources fine... Any suggestions welcome. Thanks.
Could you give an example of what stopped working? It should not have impacted any methods, but it may have conflicts with the code itself. So if you could share an example action and error message - that would help.
I had an afterSave action to simple show a notification of the 'id', running when a record was edited.
After I impliented it as a nested resource, it doesn't trigger.
Hmm, I'm not sure why this would be the case. I would try to add dumps in multiple places to see why it doesn't get triggered.
We did not touch any of these methods so it's weird that they stopped working and calling hooks :/
Thank you for your replies.
I'll report back what I discover.
The list page works as in the tutorial but when I use it with getRecordSubNavigation, it gives this error. Kindly help. 😢
I tried the url() in the navigationItem for a page class. right now they are set to static and cannot be overridden in a ListRecord class. trying to override NavigationItem gives the error
Sorry, I can't help you with sub navigation as I haven't used nested resources with it... This one you will have to debug and see why it happens
I have debugged and found that the issue is coming from NavigationItem isActiveWhen() and Url() as they try to resolve the url from their own resource instead of the parent resource.
I am unable to find a solution though as getNavigationItems is static and we cannot override the url using $this->parent.
Can I make more than 2 nested resources with this approach?
this only supports 1 level of nesting. Going deeper is a lot harder
dear all i use to create but it don't fixin with my require
here is what i want i have series, seasons,episodes
but record is only one get how do i make
Model
Series have many Season Season have belongto series and have many episodes episodes have belongto series
So route should be like that series/{record}/seasons/{record}/episodes
how can i make please guide me
Hi,
It is currently not possible to make more than one level of nested resources. So the max you can do is:
series/{record}/seasons
That's it, you can't do episodes on top.
can we do it for multiple nested resource files? like courses has different modules and that modules have many lessons, like wise? Course will be main parent, module will be child of course and parent of lesson, lesson will be child of module. Please consider this also.
Hi, as mentioned in multiple previous comments - no, it is not possible to build more than 1 nested resource with this method
Following this tutorial, I was able to add nested resources. How can I nest a custom Page to a parent resource?
The custom page is called settings, and It has a form with a bunch of fields.
I added the route to the parent's getPages(), like it was just another List/Create/Edit view:
The above will throw the following exception: