Relation Querying
Query through relations and filter by relation existence.
Relation querying has three common forms:
For: query the target side for one source model;WhereHas: keep source rows that have matching related rows;WhereDoesntHave: keep source rows that do not have matching related rows.
For
comments, err := db.Use[Comment]().
For(article.Comments()).
OrderByDesc("ID").
Get(ctx)
For applies the relation’s foreign-key condition automatically.
One-to-one:
cover, err := db.Use[Image]().For(article.Cover()).First(ctx)
Many-to-many:
tags, err := db.Use[Tag]().For(article.Tags()).Get(ctx)
WhereHas
articles, err := db.Use[Article]().
WhereHas(Article{}.Comments(), func(q *oro.RelationQuery) {
q.Where("Status", "approved")
}).
Get(ctx)
The callback is optional:
articles, err := db.Use[Article]().WhereHas(Article{}.Comments()).Get(ctx)
OrWhereHas
articles, err := db.Use[Article]().
Where("Status", "published").
OrWhereHas(Article{}.Comments(), func(q *oro.RelationQuery) {
q.Where("Pinned", true)
}).
Get(ctx)
WhereDoesntHave
articles, err := db.Use[Article]().
WhereDoesntHave(Article{}.Comments(), func(q *oro.RelationQuery) {
q.Where("Status", "approved")
}).
Get(ctx)
The callback is optional when any related row should be excluded.