Skip to content

fix: prevent duplicate resource table() invocation in InteractsWithCustomFields [3.x]#140

Merged
ManukMinasyan merged 1 commit into3.xfrom
fix/interacts-with-custom-fields-double-table-3x
Apr 21, 2026
Merged

fix: prevent duplicate resource table() invocation in InteractsWithCustomFields [3.x]#140
ManukMinasyan merged 1 commit into3.xfrom
fix/interacts-with-custom-fields-double-table-3x

Conversation

@ManukMinasyan
Copy link
Copy Markdown
Collaborator

Summary

InteractsWithCustomFields::table() invoked the resource's table() method a second time after Filament's ListRecords::makeTable() had already applied it via configureTable(). Because Filament does not deduplicate queryScopes, every modifyQueryUsing closure registered in the resource ran twice — duplicating withExists, withSum, whereNull, and similar clauses in the generated SQL and roughly doubling list-page query cost. Filters, columns, and actions were also registered twice (though idempotent by name, so no visible UI duplication).

Root cause

  • Filament/Resources/Pages/ListRecords.phpmakeTable() calls static::getResource()::configureTable($table).
  • Filament/Resources/Resource.phpconfigureTable() invokes static::table($table) on the resource.
  • Filament/Tables/Concerns/InteractsWithTable.php — Livewire then calls $this->table($this->makeTable()), which resolves to the trait.
  • The trait previously called static::getResource()::table($table) a second time, re-running every resource-defined scope.
  • Filament/Tables/Table/Concerns/HasQuery.phpmodifyQueryUsing appends to queryScopes without deduplication.

For RelationManager, the old try/catch fell through to parent::table($table) (a no-op), so relation managers are unaffected by the change.

Change

Remove the redundant static::getResource()::table($table) call. The $table argument already carries the resource's configuration when the trait receives it, so the trait now layers the custom-field columns, filters, and customFieldValues eager load on top of the already-configured table.

Test plan

  • Added regression test it invokes resource table() only once when InteractsWithCustomFields is used — asserts the resource's table() method is called exactly once.
  • Regression test fails on 3.x before this change (count is 2) and passes after.
  • Pint clean, PHPStan clean.
  • Full ListRecordsTest Pest run introduces no new failures (2 pre-existing $logo view failures unrelated to this fix remain unchanged).

Credit

Reported by Kenneth Sese with precise diagnosis and reproducer.

…stomFields

Filament's ListRecords::makeTable() already applies the resource's table()
configuration via configureTable(). The trait then re-invoked
static::getResource()::table($table), causing every modifyQueryUsing,
filter, column, and action to be registered twice. Since Filament does
not deduplicate queryScopes, a resource scope like withExists/withSum or
whereNull('parent_id') resulted in duplicated subqueries and WHERE
clauses, roughly doubling list-page query cost.

The trait now returns the already-configured table unchanged before
layering custom-field columns, filters, and the customFieldValues eager
load on top.

Reported by Kenneth Sese.
Copilot AI review requested due to automatic review settings April 20, 2026 18:16
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a performance regression where InteractsWithCustomFields::table() re-invoked the resource’s table() configuration, causing Filament query scopes (and other table configuration) to be applied twice on List pages.

Changes:

  • Remove the redundant static::getResource()::table($table) invocation from InteractsWithCustomFields.
  • Add a regression test asserting the resource table() method is called exactly once when the concern is used.
  • Add a call counter on the PostResource fixture to support the regression test.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
src/Concerns/InteractsWithCustomFields.php Stops double-applying the resource table configuration; now only layers custom-field columns/filters and eager-loading onto the already-configured table.
tests/Fixtures/Resources/Posts/PostResource.php Adds a static counter incremented by table() to detect duplicate invocations during tests.
tests/Feature/Integration/Resources/Pages/ListRecordsTest.php Adds a regression test to ensure the resource table() is invoked only once when InteractsWithCustomFields is present.

@ManukMinasyan ManukMinasyan merged commit 3a7e9c2 into 3.x Apr 21, 2026
7 checks passed
@ManukMinasyan ManukMinasyan deleted the fix/interacts-with-custom-fields-double-table-3x branch April 21, 2026 10:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants