Proper reversal of relations in sub queries - #171
Open
nilmerg wants to merge 4 commits into
Open
Conversation
nilmerg
force-pushed
the
fix/proper-reversal-of-relations-in-sub-queries-170
branch
6 times, most recently
from
August 25, 2026 15:42
f6504d3 to
bdcf355
Compare
This is required to establish type symmetry as the base's methods also accept `NULL` to be able to direcly pass a getters return value to the appropriate setter.
There is now `Relation::bindTo(Model, string, Resolver)` in order to pass control to relations how they're prepared. Since the introduction of `BelongsToMany`, it is established that a relation may resolve to multiple hops and thus needs to perform steps n-times rather than a single time. It's this reason because registering the alias and resolving the filter is now a responsibility of a relation rather than the resolver. Relations know it better how to and the override of `bindTo` in `BelongsToMany` proves it as it turned out that it is necessary to allow referencing the junction table in either the filter or the through filter in order to be able to better reverse relations. Qualification must be done by a relation in turn as well, as otherwise there's a mis-match with what's allowed to reference and what can be qualified. My initial attempt was to teach `Relation::resolve()` this, but without passing it the resolver and changing the return value this doesn't make sense. Sadly, this is out of the question as this is a breaking change. Say hello to `Relation::setFilterSubjects()` due to this.
Changes the way relations can be reversed drastically as it is now possible to influence the relation to use during reversal with `::setReverseName(string)` which allows Icinga DB Web to drop the error-prone `to.from` and `from.to` relations. An additional change is that it is now not mandatory anymore to define relations that are solely being required because of sub-queries. Missing relations on the reversed path are automatically registered. For this, each relation type now has its specific counterpart which is possible to override with `::setReverseClass(class-string)`. The default however, is to use the same type which is the case for `BelongsToOne` and `BelongsToMany`. For `BelongsTo` a sane override has been chosen that is based on how it's used at the moment in our products, as `HasOne` and `HasMany` may both be appropriate. But the latter clearly is used more often.
Since `::reverse()` uses the source's table alias by default as reverse name, a deprecation notice is triggered if the original forward path uses a different name, indicating that it is necessary to use this name as explicit reverse name. fixes #170
nilmerg
force-pushed
the
fix/proper-reversal-of-relations-in-sub-queries-170
branch
from
August 26, 2026 11:03
bdcf355 to
177dcc4
Compare
nilmerg
marked this pull request as ready for review
August 26, 2026 11:46
Member
Author
|
@BastianLedererIcinga Please note that this must not break anything in other products. Icinga DB Web for example must still work without Icinga/icingadb-web#1398, albeit with a deprecation notice here and there. |
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.
Changes the way relations can be reversed drastically as it is now possible to influence the relation to use during reversal with
::setReverseName(string)which allows Icinga DB Web to drop the error-proneto.fromandfrom.torelations.An additional change is that it is now not mandatory anymore to define relations that are solely being required because of sub-queries. Missing relations on the reversed path are automatically registered. For this, each relation type now has its specific counterpart which is possible to override with
::setReverseClass(class-string). The default however, is to use the same type which is the case forBelongsToOneandBelongsToMany. ForBelongsToa sane override has been chosen that is based on how it's used at the moment in our products, asHasOneandHasManymay both be appropriate. But the latter clearly is used more often.Since
::reverse()uses the source's table alias by default as reverse name, a deprecation notice is triggered if the original forward path uses a different name, indicating that it is necessary to use this name as explicit reverse name.fixes #170
--
A substantial preparation for this is the introduction of
Relation::bindTo(Model, string, Resolver)in order to pass control to relations how they're prepared. Since the introduction ofBelongsToMany, it is established that a relation may resolve to multiple hops and thus needs to perform steps n-times rather than a single time. It's this reason because registering the alias and resolving the filter is now a responsibility of a relation rather than the resolver.Relations know it better how to and the override of
bindToinBelongsToManyproves it as it turned out that it is necessary to allow referencing the junction table in either the filter or the through filter in order to be able to better reverse relations.Qualification must be done by a relation in turn as well, as otherwise there's a mis-match with what's allowed to reference and what can be qualified. My initial attempt was to teach
Relation::resolve()this, but without passing it the resolver and changing the return value this doesn't make sense. Sadly, this is out of the question as this is a breaking change. Say hello toRelation::setFilterSubjects()due to this.