Group the table search so it narrows a report instead of widening it - #118
Merged
Merged
Conversation
TableBuilder::rowsQuery() appended each searchable column as a bare
top-level orWhere, after everything query() returned and after the
model's global scopes. The predicate became
WHERE (report constraints) AND ... OR column LIKE '%term%'
so any report whose query() carried real constraints discarded them the
moment someone typed in the search box. Nothing inside query() could
prevent it: wrapping that body in a nested where() does not help, because
the orWhere sits outside that group too.
Measured in the consuming app against production data: a health and
safety report returning 115 rows returned 32,215 — the entire records
table — when searched for "a", and searching "Fire" returned 71 courses
that were not health and safety, including "Fire up your Facebook page".
The loop is now wrapped in its own where() group, so search composes as
AND (a OR b) and every report using TableBuilder becomes correct without
change.
Refs ACT-Training/people#3515
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MfdXn5v557zRZ9F6bYcjAd
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes ACT-Training/people#3515.
TableBuilder::rowsQuery()appended each searchable column as a bare top-levelorWhere, after everythingquery()returned and after the model's global scopes:So the predicate became:
Any report whose
query()carried real constraints therefore discarded them the moment someone typed in the search box. Nothing insidequery()could defend against it — wrapping that body in a nestedwhere()group does not help, because theorWheresits outside that group too.Measured impact
From the consuming app, against production data (
report.training.health-and-safety-list-table):"a"recordstable"Fire"A second report,
Resources\PayrollHistory, leaks the same way — 502 rows becomes 684 — but latently: it setsdisplaySearch(false), so the box is not rendered andsearchBycannot normally be set from the UI. It is onedisplaySearch()away from being live.The fix
The loop is wrapped in its own
where()group, so search composes asAND (a OR b). Every report usingTableBuilderbecomes correct without changing the report.Behaviour is otherwise unchanged: a leading
orWhereinside a group renders without its boolean, so the grouped SQL is the same set of terms, correctly parenthesised.Tests
Three new tests in
tests/TableBuilderSearchScopingTest.php, drivingrowsQuery()against a constrained report with a searchable column and asserting on returned rows rather than SQL strings:The first and third pass against the old code; the second fails, which is the defect.
Full suite: 10 passed. Pint clean. PHPStan reports 20 errors, all pre-existing — verified by stashing this change and re-running on clean
main, which reports the same 20 in the same files. None are inTableBuilder.phpor the new test.After this merges
The consuming app pins
act-training/query-builder: ^2.4.1. This wants a2.4.2release and acomposer updateinpeoplebefore ACT-Training/people#3515 can be closed — and until it ships, any new report with a constrained query still needsdisplaySearch(false).🤖 Generated with Claude Code
https://claude.ai/code/session_01MfdXn5v557zRZ9F6bYcjAd