Prefetching a 'required hasMany relationship' can have unexpected results. #1418
Replies: 2 comments 3 replies
-
Hello @dawilliams-gpsw, Thanks for asking this question about an obscure feature! The documentation is slightly misleading, so we may have to find a better way to put it.
This is correct.
The wording should be enhanced.
struct Team: TableRecord {
static let players = hasMany(Player.self)
}
struct Membership: FetchableRecord {
var team: Team
var player: Player
}
// - (team A, player 1)
// - (team A, player 2)
// - (team B, player 3)
let memberships = try Team
.including(required: Team.players)
.asRequest(of: Membership.self)
.fetchAll(db) With This use case is not frequent, and I never took the time to document it properly.
This is not true, and probably inferred from the wording of the documentation. As said in the previous example, it joins all associated records.
If you want to decode a struct that contains an array of associated records, then you must use If you want to avoid empty arrays of associated records, then, yes, |
Beta Was this translation helpful? Give feedback.
-
@groue hey I have similar question for you, it might be even more complex as it contains more associations.
This is a snipper of my code, had to reduct some of it as it has many properties. I'm not able to fetch |
Beta Was this translation helpful? Give feedback.
-
Hello all! I was recently using the
.including(required:)
API and noticed some behavior that I didn't catch when first reading through the documentation on associations. In particular, this part in this section — https://github.com/groue/GRDB.swift/blob/master/Documentation/AssociationsBasics.md#includingrequired , emphasis mine:Should this API be restricted to types that are not
to-many
relationships, or would that break compositional query language described in the docs? It was confusing for me, because I was expecting to prefetch all of the relationships, similar toincluding(all:)
to fill out a 'info' type struct:I see that this uses a row adapter under the hood and only joins the first record in the relationship, and thus my
bars
arenil
when I expected them to be the prefetched records. This becomes slightly more obvious when I remove optionality fromFooWithBars
because the decoding ends up failing and that led me to the docs to find the part I had previously missed regarding only fetching one associated record from the relationship.If I'm not mistaken, I think the solution for me is to add a
.having(...)
that checks if the association is not empty, but I am wondering if this is something that GRDB could (should?) do under the hood if decoding to a collection.Beta Was this translation helpful? Give feedback.
All reactions