F
Filament8mo ago
Vp

How to eager load relationship inside infolist repeatable entry

I've enable prevent lazy loading like this in providers Model::preventLazyLoading(! $this->app->isProduction()); I create a relationship manager and I display the data in infolist. but when it comes to repeatable entry like below example, I always got this error Attempted to lazy load [customer] on model [App\Models\Reply] but lazy loading is disabled.
protected static string $relationship = 'comments';

public function infolist(Infolist $infolist): Infolist
{
return $infolist
->schema([
// ...

Infolists\Components\RepeatableEntry::make('replies')
->schema([
Infolists\Components\TextEntry::make('customer.name'),
]),
]);
}

// Comment model
public function replies(): HasMany
{
return $this->hasMany(Reply::class);
}

// Reply model
public function customer(): BelongsTo
{
return $this->belongsTo(Customer::class);
}
protected static string $relationship = 'comments';

public function infolist(Infolist $infolist): Infolist
{
return $infolist
->schema([
// ...

Infolists\Components\RepeatableEntry::make('replies')
->schema([
Infolists\Components\TextEntry::make('customer.name'),
]),
]);
}

// Comment model
public function replies(): HasMany
{
return $this->hasMany(Reply::class);
}

// Reply model
public function customer(): BelongsTo
{
return $this->belongsTo(Customer::class);
}
I can put protected $with = ['customer']; inside Model, but it's not a great solution IMO, so what should be the best way to eager load the relationship
Solution:
Yes, so helpful.. Now I use ->modifyQueryUsing() and load relationship. it's working now, thanks
Jump to solution
20 Replies
Jigar D
Jigar D8mo ago
How to eager load in Relation Manager? - Filament
Hey guys, I am trying to optimise my app. So I used this: Model::shouldBeStrict(app()->isLocal()); I found one problem in my RelationManager. I have User that has many Clients and he belongs to Address. When I want to edit User I got this error: https://flareapp.io/share/dPbNO6LP#F129
Solution
Vp
Vp8mo ago
Yes, so helpful.. Now I use ->modifyQueryUsing() and load relationship. it's working now, thanks
mark.cameron
mark.cameron7mo ago
@Vp Where did you put the ->modifyQueryUsing() ? I get a method doesn't exist on the Infolist when I try it like this:
return $infolist
->modifyQueryUsing(...)
->schema([
return $infolist
->modifyQueryUsing(...)
->schema([
It only appears to work on $table, but that has no effect on ths Infolist display when viewing the model... Thanks for your help!
Vp
VpOP7mo ago
I put in $table and I just use it inside infolist Example:
return $table
->modifyQueryUsing(fn ($query) => $query->with([
'replies' => fn ($reply) => $reply->with('parent'),
]))
...

return $infolist
->schema([
Infolists\Components\RepeatableEntry::make('replies')
->schema([
Infolists\Components\TextEntry::make('parent.name),
return $table
->modifyQueryUsing(fn ($query) => $query->with([
'replies' => fn ($reply) => $reply->with('parent'),
]))
...

return $infolist
->schema([
Infolists\Components\RepeatableEntry::make('replies')
->schema([
Infolists\Components\TextEntry::make('parent.name),
mark.cameron
mark.cameron7mo ago
Ok thanks for the example, but I still get the but lazy loading is disabled message for the relationship that I define in the modifyQueryUsing(). Not sure what I am missing... But even debugging the modifyQueryUsing(), and I'm not passing through it when on the Infolist...
Vp
VpOP7mo ago
can you share some codes in which part it shows lazy load disabled?
mark.cameron
mark.cameron7mo ago
It's all vendor stuff
mark.cameron
mark.cameron7mo ago
This is the code for the table() and infolist() methods on the resource
mark.cameron
mark.cameron7mo ago
My relation is the contactables one and using the with('contact')
Vp
VpOP7mo ago
I am not sure but below part maybe the suspect, what is this $record contains? It looks like it's not load relationship. for me I just use normal ViewAction
->recordUrl(
fn (News $record): string => route(static::getRouteBaseName() . '.view', [
'record' => $record,
'tenant' => Filament::getTenant()
]),
);
->recordUrl(
fn (News $record): string => route(static::getRouteBaseName() . '.view', [
'record' => $record,
'tenant' => Filament::getTenant()
]),
);
mark.cameron
mark.cameron7mo ago
ahh, is yours in a modal ?
Vp
VpOP7mo ago
wdym?
mark.cameron
mark.cameron7mo ago
As in, is yours a simple resource? And when you click on view, it display the resource in a Modal, and not on it's own page?
Vp
VpOP7mo ago
Yes, only modal.. I use slideOver() as well 😆 If you use full page (own page) then I think you need to load realtionship on that page
mark.cameron
mark.cameron7mo ago
Ok that might explain it, as I'm on a new page the relationship query isn't called from the $table... Ok thanks I'll have a look there
Vp
VpOP7mo ago
🆒
mark.cameron
mark.cameron7mo ago
Thanks for your help!
Vp
VpOP7mo ago
Wc
mark.cameron
mark.cameron7mo ago
For future visitors: You can do something like this to eager load the relationship on the "View" page for your resource by overriding the mount() method, might be other ways or cleaner ways, but I couldn't see any other way to interact with the query:
<?php

...

class ViewNews extends ViewRecord
{
protected static string $resource = NewsResource::class;

#[\Override]
public function mount(int | string $record): void
{
parent::mount($record);

$this->record->load('contactables.contact', 'contactables.category');
}

...
}
<?php

...

class ViewNews extends ViewRecord
{
protected static string $resource = NewsResource::class;

#[\Override]
public function mount(int | string $record): void
{
parent::mount($record);

$this->record->load('contactables.contact', 'contactables.category');
}

...
}
Epko
Epko2w ago
Thanks Mark, your solution almost worked, but when I also have an Action button on the InfoList, it triggers the lazy loading error once again. Turns out this is the way to do it:
$record = $infolist->getRecord()->load('rel.subrel');
return $infolist
->record($record)
$record = $infolist->getRecord()->load('rel.subrel');
return $infolist
->record($record)
And if you use an Action in the Infolist that also uses a relationship that should be eager loaded:
->form(function (SomeModel $record) {
$record->load('rel.subrel');
->form(function (SomeModel $record) {
$record->load('rel.subrel');
Want results from more Discord servers?
Add your server