The performance decreased because of a combination of calls that were supposed to increase performance.
We have a mechanism in place which automatically eager loads models needed in the element representers when a collection of them is rendered. This is to avoid N+1 queries of course. But, if eager loading is combined with e.g., a LIMIT, which we do because we paginate, rails automatically falls back to issuing two instead of just one SQL statement. Which makes sense as otherwise LEFT JOINS might mess with the result set.
But Rails does so in a somewhat simple fashion. It uses the first query to get the DISTINCT ids. The second is used to load the values (without a limit). But instead of removing all WHERE statements in the second SQL statement and then apply just the one for the ids, it keeps the original WHERE statement and applies the one for the ids on top. The problem with that is that the database trips on that (I didn't check the why) and uses a less than optimal query plan.
That was the problem here as well. The first query remained reasonable quick (300ms) but the second one took 25s.
The fix is to split the two statements by hand in the representer whenever eager loading is defined. The first query has all the filters but no eager loading and fetches the ids. The second takes the ids, and with eager loading included loads the data. Et voila, second query takes 10ms.
That at least works for relations, work_packages and projects. But there are other representers that also seem to have custom behaviour. I'm looking into whether they can be easily adapted.
[#68702] Clean up custom field filter spec
[#68702] Clean up Project table spec
[#68702] Add project list filter spec for groups and placeholder users
[#68702] User filter matches group membership
[#68702] Add specs for group membership filtering
Filters are now defined declaratively during tool definition.
In addition to simple where-based filters (like the ones we've been
using in SearchProject), we now also support using query filters
that are defined for other purposes already. Though we keep supporting
custom filtering, since pre-existing classes are often not available
and necessary for very simple filtering operations.
As a side-find, specs for the ProjectStatusFilter have been extended.
./spec/models/queries/work_packages/filter/typeahead_filter_spec.rb:96
Since the status is now also searched in, using the id of a work package as the search string can collide with the name of the status having an incremented integer as part of the name
* [#56831] Add work package type, status and meta status to what the global search is searching on during typeahead
https://community.openproject.org/work_packages/56831
* Add placeholder text with better instructions to the global search
* Add specs for typeahead_filter
* Improve global search placeholder
It's not possible to use allow_any_instance_of(Plaintext::Resolver).to
receive(:text) since we prepended a module which overrides the #text
method.
And the extra `#reload` calls and `allow(attachment).to
receive(:readable?).and_return(true)` were not needed.
This is consistent with what we expose via the API, where we never tried
to hide this data. It was effectively only hidden from the UI.
We couldn't come up with a reason why it was hidden from the UI back then,
but since we now needed to expose updated_at to everyone (previous commit),
it only made sense to consistently also allow created_at to be seen by everyone.
The main motivation to add this was to allow filtering by it via API.
Though consistently, we've now enabled it to be usable from the UI as well,
where updated_at is now available as a column and for filtering and ordering.
Favorite is the correct term in the context of expressing a preference
for a particular project / other OpenProject domain object.
Updates `ActsAsFavorable` to `ActsAsFavoritable`, as well as filenames,
identifiers and strings to:
favored => favorited
favorable => favoritable
favoring => favoriting
* Add BudgetRelation, fixed budget
* Add fixed_budget editing to budget form
* Show and allow setting the budget state
* Rename fixed_budget to supplementary_amount to make it a factor of the budget
* Add an `available` method so we don't have to calculate this all the time
* Add a section to the show budget page to display amounts
* Highlight totals
* Add tests and allocation + spent for children
* Show budget allocated to children in budget show
* Add an allocated to children column
* show children in the page
* Implement bottom->up addition approach
* remove unused DB column and make sure each budget only has one parent
* Add budget relation controller
* Remove names for budgets in specs
* Refactor tests to use `have_attributes`
* re-add appropriate names for spec factories