Skip to main content

Filtering by relations

ant.Has filters rows by what they're related to, without loading anything. Each one becomes an EXISTS inside the same query, so it costs no extra round trip.

writers, err := db.Users.Where(ant.Has(&U.Posts)).All(ctx)

Add conditions on the related row.

drafting, err := db.Users.Where(ant.Has(&U.Posts, ant.Eq(&P.Published, false))).All(ctx)

Has none​

silent, err := db.Users.Where(ant.HasNone(&U.Posts)).All(ctx)

HasNone with conditions matches rows with no related row that meets them.

The other direction​

ant.HasOne follows a many-to-one or one-to-one relation.

byAdults, err := db.Posts.Where(ant.HasOne(&P.User, ant.Gt(&U.Age, 18))).All(ctx)

Combining​

These are conditions like any other.

young, err := db.Users.Where(ant.Has(&U.Posts), ant.Lt(&U.Age, 18)).All(ctx)

same, err := db.Users.Where(ant.Not(ant.Has(&U.Posts))).Count(ctx)

They work on many-to-many and through relations too, and a global filter on the related model still applies.

Build it at run time

ant.Has needs the related model's configuration, which exists once a context has opened. Call it where the query is built, not in a package variable.