Add R.Loaded to track which relationships have been loaded#671
Merged
stephenafamo merged 4 commits intoMay 8, 2026
Conversation
Owner
|
I'm not sure about this, because it reserves a relationship name |
Contributor
Author
|
I can make the "Loaded" name configurable in the bobgen config, so users can change it themselves, rather than aliasing their own relations in case of conflict? |
Owner
|
Alright, I like that idea 👍🏾 |
Contributor
Author
|
It's updated now :) |
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.
Why
Today, the only way to inspect whether a generated relationship has been loaded is to look at the value in
R. That collapses two distinct states into one:model.R.Pilot == nilcould mean "never loaded" or "loaded, no related row".len(model.R.Jets) == 0could mean "never loaded" or "loaded, zero rows" (loaders reset toniland thenappend, so the zero-row case is indistinguishable from never-loaded).Callers have no reliable way to tell these apart, which is a real footgun when the FK is nullable or the related set may
legitimately be empty.
Solution
A new typed struct, nested inside
RasR.Loaded, with oneboolper relationship.R.Loaded.Xis set to true by:LoadX,Preload.X, andThenLoad.Xafter they populateR.X(including the zero-row case).AttachX/InsertXfor to-one relations, where the relation is fully known after the call.BuildandCreateR.Loaded.Xis not changed byAttachX/InsertXfor to-many relations, since appending rows does not turn a partial slice into a complete one.Behaviour change: slice
LoadXnow resets stale to-one valuesIn
110_loaders.go.tpl, the per-parent reset loop in both slice-load paths previously ran only for to-many relations - sliceLoadXon a to-one relation would leave a staleR.Xin place if the new query returned no match for that parent. Single-objectLoadXalready reset, so the two paths were inconsistent.We remove the
{{if $rel.IsToMany}}guard around that reset, so sliceLoadXon a to-one now also clearsR.Xper parent before the inner match loop. This is required for the newR.Loadedcontract to hold - without it, a parent could end up withLoaded.X == truewhileR.Xstill points at a row from an earlier load.Other Notes
Loadedis now reserved; generation fails with a clear error if any relationship is aliased that way.R.Loaded