Query Scopes
Scopes are reusable query fragments. Nimbus provides built-in scopes for common patterns, and you can define custom scopes as functions that accept *gorm.DB and return *gorm.DB.
Custom Scopes
func Published(db *gorm.DB) *gorm.DB {
return db.Where("status = ?", "published")
}
func Recent(db *gorm.DB) *gorm.DB {
return db.Where("created_at > ?", time.Now().AddDate(0, 0, -30))
}
// Usage
var posts []Post
db.Model(&Post{}).Scopes(Published, Recent).Find(&posts)
Scopes with Arguments
func Status(status string) func(*gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.Where("status = ?", status)
}
}
func OlderThan(days int) func(*gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.Where("created_at < ?", time.Now().AddDate(0, 0, -days))
}
}
db.Model(&Post{}).Scopes(Status("draft"), OlderThan(7)).Find(&posts)
Built-in Scopes
Nimbus includes pre-built scopes in the database package:
| Scope | SQL | Description |
|---|---|---|
WhereScope(col, val) | WHERE col = val | Simple equality filter |
OrderScope(expr) | ORDER BY expr | Order results |
LatestScope(col) | ORDER BY col DESC | Newest first |
OldestScope(col) | ORDER BY col ASC | Oldest first |
LimitScope(n) | LIMIT n | Limit results |
WhenScope(cond, scope) | Conditional | Apply scope only when condition is true |
import "github.com/CodeSyncr/nimbus/database"
// Latest posts
db.Scopes(database.LatestScope("created_at"), database.LimitScope(10)).Find(&posts)
// Conditional scope (filter by status only if parameter provided)
status := c.Query("status", "")
db.Scopes(
database.WhenScope(status != "", database.WhereScope("status", status)),
database.LatestScope("created_at"),
).Find(&posts)
Soft Delete Scopes
When models use gorm.DeletedAt, soft-deleted records are auto-excluded. Use these scopes to include them:
// Include soft-deleted records
db.Scopes(database.WithTrashed).Find(&posts)
// Only soft-deleted records
db.Scopes(database.OnlyTrashed).Find(&posts)
// Restore a soft-deleted record
database.Restore(db, &post)
// Permanently delete (bypass soft delete)
database.ForceDelete(db, &post)
// Check if model is soft-deleted
if database.IsTrashed(&post) {
// ...
}
Combining Scopes
// Build queries dynamically
scopes := []func(*gorm.DB) *gorm.DB{
database.LatestScope("created_at"),
}
if filterStatus != "" {
scopes = append(scopes, Status(filterStatus))
}
if onlyRecent {
scopes = append(scopes, Recent)
}
db.Model(&Post{}).Scopes(scopes...).Find(&posts)