processwire-issues icon indicating copy to clipboard operation
processwire-issues copied to clipboard

How to use joinFields with PageTable?

Open tuomassalo opened this issue 11 months ago • 0 comments

I'm trying to optimize numerous occasions in a codebase, where the problem follows this pattern:

foreach ($parentPage->my_pagetable_field as $page) {
  // accessing $page->field1 or $page->field2 causes more database queries.
}

If the loop iterates through 100 pages, addressing four fields, that's 400 queries.

Things I've tried

  • I could enable autojoin for the fields, but that's not always viable: elsewhere in the code, the same fields and templates might be used in different ways.
  • The new preload() feature would help to reduce the example case from 400 to 100 queries, but that's still 100 too many.
  • I could also just get the page ids and use them to rebuild a find() selector, but that's clumsy, breaks easily (since I need to copy the PageTable field rules to the selector) and causes an extra query with a long WHERE pages_id IN (...) condition:
$ids = [];
foreach ($parentPage->my_pagetable_field as $page) {
  $ids[] = $page->id;
}

$pages = $this->pages->find("template=..., id=" . implode('|', $ids), ['joinFields' => [...]]);

Suggestion for a possible fix

Ideally, I would like to be able to specify joinFields when fetching the field, something like:

foreach ($parentPage->my_pagetable_field(['joinFields' => ['field1', ...]]) as $page) {

(Not sure if this syntax is viable.)

Another approach would be to be able to specify joinFields in PageTable settings, like now there is sortfields.

See also: https://github.com/processwire/processwire/pull/304/files - with this patch, I could just add the relevant fields to sortfields, but that seems a bit silly when I'm not interested in sorting.

Any thoughts? Or am I missing a simple, existing solution?

tuomassalo avatar Jan 27 '25 11:01 tuomassalo