OOro

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.

Edit this page