Documentation
¶
Index ¶
- type BelongsTo
- type DispatchesEvents
- type Event
- type EventType
- type Factory
- type HasMany
- type HasManyThrough
- type HasOne
- type HasOneThrough
- type Many2Many
- type ModelToObserver
- type ModelWithConnection
- type ModelWithGlobalScopes
- type ModelWithMorphClass
- type ModelWithRelations
- type ModelWithTableName
- type MorphMany
- type MorphOne
- type MorphRelationCallback
- type MorphTo
- type MorphToMany
- type MorphedByMany
- type Observer
- type ObserverWithCreating
- type ObserverWithDeleting
- type ObserverWithForceDeleting
- type ObserverWithRestored
- type ObserverWithRestoring
- type ObserverWithRetrieved
- type ObserverWithSaved
- type ObserverWithSaving
- type ObserverWithUpdating
- type Orm
- type PivotCallback
- type PivotQuery
- type Query
- type QueryWithClone
- type QueryWithContext
- type QueryWithObserver
- type QueryWithRelations
- type Relation
- type RelationCallback
- type RelationCount
- type RelationKind
- type RelationWriter
- type ToSql
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BelongsTo ¶
type BelongsTo struct {
Related any
// ForeignKey is the column on the parent table referencing the related row. Optional.
ForeignKey string
// OwnerKey is the column on the related table referenced by ForeignKey. Optional, "id".
OwnerKey string
OnQuery RelationCallback
}
BelongsTo declares the inverse of HasOne / HasMany — this model holds a foreign key referencing the related row.
Defaults: ForeignKey = singular(relatedTable) + "_id"; OwnerKey = "id".
func (BelongsTo) Kind ¶
func (BelongsTo) Kind() RelationKind
type DispatchesEvents ¶
type Event ¶
type Event interface {
// Context returns the event context.
Context() context.Context
// GetAttribute returns the attribute value for the given key.
GetAttribute(key string) any
// GetOriginal returns the original attribute value for the given key.
GetOriginal(key string, def ...any) any
// IsClean returns true if the given column is clean.
IsClean(columns ...string) bool
// IsDirty returns true if the given column is dirty.
IsDirty(columns ...string) bool
// Query returns the query instance.
Query() Query
// SetAttribute sets the attribute value for the given key.
SetAttribute(key string, value any)
}
type EventType ¶
type EventType string
const ( // Create events EventCreating EventType = "creating" EventCreated EventType = "created" // Update events EventUpdating EventType = "updating" EventUpdated EventType = "updated" // Save events EventSaving EventType = "saving" EventSaved EventType = "saved" // Delete events EventDeleting EventType = "deleting" EventDeleted EventType = "deleted" EventForceDeleting EventType = "force_deleting" EventForceDeleted EventType = "force_deleted" // Restore events EventRestoring EventType = "restoring" EventRestored EventType = "restored" // Retrieve events EventRetrieved EventType = "retrieved" )
type Factory ¶
type Factory interface {
// Count sets the number of models that should be generated.
Count(count int) Factory
// Create creates a model and persists it to the database.
Create(value any, attributes ...map[string]any) error
// CreateQuietly creates a model and persists it to the database without firing any model events.
CreateQuietly(value any, attributes ...map[string]any) error
// Make creates a model and returns it, but does not persist it to the database.
Make(value any, attributes ...map[string]any) error
}
type HasMany ¶
type HasMany struct {
Related any
ForeignKey string
LocalKey string
OnQuery RelationCallback
}
HasMany declares a one-to-many relation — the multi-result variant of HasOne.
Defaults: ForeignKey = singular(parentTable) + "_id"; LocalKey = "id".
func (HasMany) Kind ¶
func (HasMany) Kind() RelationKind
type HasManyThrough ¶
type HasManyThrough struct {
Related any
Through any
FirstKey string
SecondKey string
LocalKey string
SecondLocalKey string
OnQuery RelationCallback
}
HasManyThrough is the multi-result variant of HasOneThrough.
func (HasManyThrough) Kind ¶
func (HasManyThrough) Kind() RelationKind
type HasOne ¶
type HasOne struct {
// Related is a sample instance of the related model (e.g. &Profile{}).
Related any
// ForeignKey is the column on the related table referencing the parent. Optional.
ForeignKey string
// LocalKey is the column on the parent referenced by ForeignKey. Optional, defaults to "id".
LocalKey string
// OnQuery is a default scope applied to every query built for this relation (eager loads,
// existence checks, aggregates, Related). Applied before any caller-supplied callback.
OnQuery RelationCallback
}
HasOne declares a one-to-one relation where the related row holds a foreign key referencing this model.
Defaults: ForeignKey = singular(parentTable) + "_id"; LocalKey = "id".
func (HasOne) Kind ¶
func (HasOne) Kind() RelationKind
type HasOneThrough ¶
type HasOneThrough struct {
Related any
// Through is the intermediate model.
Through any
// FirstKey is the FK on the through table pointing at parent. Optional.
FirstKey string
// SecondKey is the FK on the related table pointing at through. Optional.
SecondKey string
// LocalKey is the PK on the parent referenced by FirstKey. Optional, "id".
LocalKey string
// SecondLocalKey is the PK on the through table referenced by SecondKey. Optional, "id".
SecondLocalKey string
OnQuery RelationCallback
}
HasOneThrough declares a relation reached through an intermediate ("through") table.
Defaults:
FirstKey = singular(parentTable) + "_id" SecondKey = singular(throughTable) + "_id" LocalKey = "id" SecondLocalKey = "id"
func (HasOneThrough) Kind ¶
func (HasOneThrough) Kind() RelationKind
type Many2Many ¶
type Many2Many struct {
Related any
// Table is the pivot table name. Optional.
Table string
// ForeignPivotKey is the pivot column referencing the parent. Optional.
ForeignPivotKey string
// RelatedPivotKey is the pivot column referencing the related. Optional.
RelatedPivotKey string
// ParentKey is the column on the parent referenced by ForeignPivotKey. Optional, "id".
ParentKey string
// RelatedKey is the column on the related referenced by RelatedPivotKey. Optional, "id".
RelatedKey string
// PivotField is the name of the struct field on the related model that the eager loader will
// hydrate with pivot column values (e.g. "Pivot", "UserPivot"). Optional — defaults to
// "Pivot". The field's Go type drives both the pivot SELECT list (every db-tagged column on
// the struct) and the hydration target. When the related model has no field by this name,
// no Pivot hydration happens — the relation still works for joining, just doesn't surface
// pivot columns. Use a non-default name when one related model serves multiple m2m relations
// with different pivot schemas (e.g. Role with both UserPivot and GroupPivot fields).
PivotField string
// PivotTimestamps enables auto-stamping of the pivot table's created_at / updated_at columns
// on Attach / Sync / Save (and updated_at on UpdateExistingPivot), using default column names.
// Most users don't need to set this flag explicitly — see "Detection priority" below.
//
// Detection priority for pivot timestamps (highest first):
//
// 1. Pivot struct field with `gorm:"autoCreateTime"` / `gorm:"autoUpdateTime"` tag. Works
// for any field name; column name is taken from the struct's GORM schema.
// 2. Pivot struct field named CreatedAt / UpdatedAt of type time.Time (Go/GORM convention).
// 3. PivotTimestamps: true. Fallback for when no Pivot struct is declared (or its struct
// has no timestamp fields) but the underlying table still has created_at / updated_at
// columns you want auto-filled. Uses default column names.
//
// Customize column names via `gorm:"column:..."` on the Pivot struct field. There is
// intentionally no relation-level override — the Pivot struct is the single source of truth
// for column metadata.
PivotTimestamps bool
OnQuery RelationCallback
// OnPivotQuery scopes pivot-table SELECT / UPDATE / DELETE for Sync / Detach /
// UpdateExistingPivot operations on this relation. Equality conditions added here are NOT
// auto-injected into Attach INSERT rows — pass them via Attach attrs if needed.
OnPivotQuery PivotCallback
// Touches, when true, causes Sync / Attach / Detach / Toggle / UpdateExistingPivot on this
// relation to bump the parent's `updated_at` after the pivot write completes (and only when
// the operation actually changed pivot rows). Mirrors fedaco's `touchIfTouching`. Silently
// no-ops when the parent's schema doesn't carry an updated_at field.
Touches bool
}
Many2Many declares a many-to-many relation through a pivot table.
Defaults:
Table = alphabetical singular pair (e.g. "post_tag") ForeignPivotKey = singular(parentTable) + "_id" RelatedPivotKey = singular(relatedTable) + "_id" ParentKey = "id" RelatedKey = "id"
func (Many2Many) Kind ¶
func (Many2Many) Kind() RelationKind
type ModelToObserver ¶
type ModelWithConnection ¶
type ModelWithConnection interface {
// Connection gets the connection name for the model.
Connection() string
}
type ModelWithGlobalScopes ¶
type ModelWithMorphClass ¶
type ModelWithMorphClass interface {
MorphClass() string
}
ModelWithMorphClass lets a model override the value written to and matched against polymorphic `*_type` columns. The override takes precedence over both the global morph map (registered via orm.MorphMap) and GORM's default of using the parent's table name.
A model that wants to be aliased as e.g. "post" in polymorphic relations declares:
func (Post) MorphClass() string { return "post" }
This is the recommended primary mechanism for aliasing morph types because it co-locates the alias with the model definition. The global morph map is provided as a fallback for models the caller cannot modify (e.g. third-party types) or for teams that prefer a single boot-time registration.
type ModelWithRelations ¶
ModelWithRelations is implemented by every model that declares relationships. The single map returned by Relations() is the only place relations are declared. GORM relation struct tags (`foreignKey:`, `references:`, `many2many:`, `polymorphic:`) are forbidden — fields that hold related rows must be tagged `gorm:"-"`.
type ModelWithTableName ¶
type ModelWithTableName interface {
// TableName gets the table name for the model, without the connection prefix.
TableName() string
}
ModelWithTableName is implemented by every model, which must declare the table it is stored in.
Declaring a table is required, not optional: the ORM resolves a model's table through this method and nothing else. The framework never derives a table name from the struct name and never pluralises, so `type User struct{ ... }` addresses no table until TableName() says which one it is. The method is the single source every part of the framework consults when it needs a model's table - reads, writes, relations and the query builder alike - so there is exactly one place to change it.
A model that declares no table is a configuration error rather than something to guess around: instead of falling back to a naming strategy, the ORM fails with a named error that reports the offending type and names the TableName() method to add.
`make:model` writes this method into every model it generates.
type MorphMany ¶
type MorphMany struct {
Related any
Name string
TypeColumn string
IDColumn string
LocalKey string
OnQuery RelationCallback
}
MorphMany is the multi-result variant of MorphOne.
func (MorphMany) Kind ¶
func (MorphMany) Kind() RelationKind
type MorphOne ¶
type MorphOne struct {
Related any
// Name is the polymorphic name (e.g. "imageable", "taggable"). Required.
Name string
// TypeColumn is the polymorphic type column on the related table. Optional.
TypeColumn string
// IDColumn is the polymorphic id column on the related table. Optional.
IDColumn string
// LocalKey is the column on the parent referenced by IDColumn. Optional, "id".
LocalKey string
OnQuery RelationCallback
}
MorphOne declares a one-to-one polymorphic relation — the related row holds <Name>_id and <Name>_type referencing one of several possible parent kinds.
Defaults: TypeColumn = Name + "_type"; IDColumn = Name + "_id"; LocalKey = "id".
func (MorphOne) Kind ¶
func (MorphOne) Kind() RelationKind
type MorphRelationCallback ¶
MorphRelationCallback is the per-type variant of RelationCallback used by the *HasMorph family, matching the `function ($query, $type)` callback for whereHasMorph. The second argument is the morph type currently being scoped (the related model's morph class - the table name in GORM's polymorphic convention).
type MorphTo ¶
type MorphTo struct {
// Name is the polymorphic name. Required.
Name string
// TypeColumn is the polymorphic type column on this table. Optional.
TypeColumn string
// IDColumn is the polymorphic id column on this table. Optional.
IDColumn string
// OwnerKey is the column on each related table referenced by IDColumn. Optional, "id".
OwnerKey string
OnQuery RelationCallback
}
MorphTo declares the inverse polymorphic side: this model holds <Name>_id + <Name>_type and resolves to one of several parent kinds via the morph map registry. There is no Related — the concrete type is determined per row from the type column.
Defaults: TypeColumn = Name + "_type"; IDColumn = Name + "_id"; OwnerKey = "id".
func (MorphTo) Kind ¶
func (MorphTo) Kind() RelationKind
type MorphToMany ¶
type MorphToMany struct {
Related any
Name string
Table string
TypeColumn string
ForeignPivotKey string
RelatedPivotKey string
ParentKey string
RelatedKey string
// PivotField — see Many2Many.PivotField.
PivotField string
// PivotTimestamps — see Many2Many.PivotTimestamps.
PivotTimestamps bool
OnQuery RelationCallback
// OnPivotQuery — see Many2Many.OnPivotQuery.
OnPivotQuery PivotCallback
// Touches — see Many2Many.Touches.
Touches bool
}
MorphToMany declares a polymorphic many-to-many — through a pivot that carries <Name>_id + <Name>_type plus a related FK.
Defaults:
Table = pluralize(Name) (e.g. "taggables") TypeColumn = Name + "_type" ForeignPivotKey = Name + "_id" RelatedPivotKey = singular(relatedTable) + "_id" ParentKey = "id" RelatedKey = "id"
func (MorphToMany) Kind ¶
func (MorphToMany) Kind() RelationKind
type MorphedByMany ¶
type MorphedByMany struct {
Related any
Name string
Table string
TypeColumn string
ForeignPivotKey string
RelatedPivotKey string
ParentKey string
RelatedKey string
// PivotField — see Many2Many.PivotField.
PivotField string
// PivotTimestamps — see Many2Many.PivotTimestamps.
PivotTimestamps bool
OnQuery RelationCallback
// OnPivotQuery — see Many2Many.OnPivotQuery.
OnPivotQuery PivotCallback
// Touches — see Many2Many.Touches.
Touches bool
}
MorphedByMany is the inverse side of MorphToMany — the morph value pins on the related rather than the parent. Field semantics and defaults match MorphToMany.
func (MorphedByMany) Kind ¶
func (MorphedByMany) Kind() RelationKind
type Observer ¶
type Observer interface {
// Created called when the model has been created.
Created(Event) error
// Updated called when the model has been updated.
Updated(Event) error
// Deleted called when the model has been deleted.
Deleted(Event) error
// ForceDeleted called when the model has been force deleted.
ForceDeleted(Event) error
}
type ObserverWithCreating ¶
type ObserverWithDeleting ¶
type ObserverWithRestored ¶
type ObserverWithRestoring ¶
type ObserverWithRetrieved ¶
type ObserverWithSaved ¶
type ObserverWithSaving ¶
type ObserverWithUpdating ¶
type Orm ¶
type Orm interface {
// Config gets the database config.
Config() database.Config
// Connection gets an Orm instance from the connection pool.
Connection(name string) Orm
// DB gets the underlying database connection.
DB() (*sql.DB, error)
// Factory gets a new factory instance for the given model name.
Factory() Factory
// DatabaseName gets the current database name.
DatabaseName() string
// Name gets the current connection name.
Name() string
// Related returns a Query pre-scoped to the related rows for the given parent and relation
// name. parent must be a non-nil pointer to a struct. The returned Query is a fresh chain —
// call any of Where / OrderBy / Get / First / Count / etc. on it.
//
// Per-kind shape:
// - HasOne / HasMany: Query().Model(related).Where("<id_col>", parent.<local_key>)
// - BelongsTo: Query().Model(related).Where("<owner_key>", parent.<fk_col>)
// - MorphOne / MorphMany: HasMany shape + Where("<type_col>", desc.morphValue)
// - MorphTo: type resolved from morph map; Query().Model(<resolved>).Where("<owner_key>", parent.<id_col>)
// - Many2Many / MorphToMany / MorphedByMany: Query().Table(related).Joins("INNER JOIN <pivot> ON ...").Where("<pivot>.<parent_fk>", parent.<pk>)
// - HasOneThrough / HasManyThrough: Query().Table(related).Joins("INNER JOIN <through> ON ...").Where("<through>.<first_key>", parent.<local_key>)
//
// Mirrors fedaco's model.NewRelation('foo') for the read path. Write operations live on
// RelationWriter (see Orm.Relation) — they are not chained off this Query.
Related(parent any, relation string) Query
// Relation returns a RelationWriter bound to (parent, name) for FK-safe write operations.
// All write methods (Save / Create / UpdateOrCreate / Attach / Sync / Detach / Toggle /
// Associate / Dissociate / etc.) are reached via this builder rather than as flat methods on
// Orm — the (parent, name) pair binds once.
Relation(parent any, name string) RelationWriter
// Observe registers an observer with the Orm.
Observe(model any, observer Observer)
// Query gets a new query builder instance.
Query() Query
// Fresh resets the Orm instance.
Fresh()
// SetQuery sets the query builder instance.
SetQuery(query Query)
// Transaction runs a callback wrapped in a database transaction.
Transaction(txFunc func(tx Query) error) error
// WithContext sets the context to be used by the Orm.
WithContext(ctx context.Context) Orm
}
type PivotCallback ¶
type PivotCallback func(query PivotQuery) PivotQuery
PivotCallback scopes pivot-table reads (and the corresponding diff-driven writes) for a BelongsToMany relation. Declared via Many2Many / MorphToMany / MorphedByMany's OnPivotQuery field; applied automatically to Sync / Detach / UpdateExistingPivot and Attach's duplicate- detection SELECT.
type PivotQuery ¶
type PivotQuery interface {
// Where adds a `column op value` clause to the pivot query. operator defaults to "=" when
// only two args are passed (column, value).
Where(column string, args ...any) PivotQuery
// WhereIn adds a `column IN (...)` clause to the pivot query.
WhereIn(column string, values []any) PivotQuery
// WhereNotIn adds a `column NOT IN (...)` clause to the pivot query.
WhereNotIn(column string, values []any) PivotQuery
// WhereNull adds a `column IS NULL` clause to the pivot query.
WhereNull(column string) PivotQuery
// WhereNotNull adds a `column IS NOT NULL` clause to the pivot query.
WhereNotNull(column string) PivotQuery
}
PivotQuery is a small builder surface for scoping the pivot-table SQL emitted by Sync / Attach duplicate-skip / Detach / UpdateExistingPivot. It is intentionally narrower than the full Query interface — only the WHERE-style methods that make sense on a single-table pivot read/write are exposed. Mirrors fedaco's `wherePivot` / `wherePivotIn` / `wherePivotNull` accumulators on BelongsToMany.
NOTE: PivotQuery filters only SELECT / UPDATE / DELETE on the pivot table — equality conditions added here are NOT auto-injected into INSERT rows on Attach. Callers that need the conditions to appear on inserted rows should pass them through Attach attrs.
type Query ¶
type Query interface {
// QueryWithRelations exposes the QueriesRelationships surface (Has / WhereHas / WithCount /
// HasMorph / etc.). Embedding it into Query lets users chain relationship queries with the
// rest of the builder: q.Where(...).Has("Books", ">=", 3).Get(&users).
QueryWithRelations
// Related returns a Query pre-scoped to the related rows for parent.name. Mirrors Orm.Related
// but lives on Query so it can be used inside a Transaction callback. parent must be a
// non-nil pointer to a struct.
Related(parent any, name string) Query
// Relation returns a RelationWriter bound to (parent, name) for FK-safe write operations.
// Mirrors Orm.Relation but lives on Query so writes inside a Transaction callback honor the
// transaction.
Relation(parent any, name string) RelationWriter
// Begin begins a new transaction
// DEPRECATED Use BeginTransaction instead.
Begin() (Query, error)
// BeginTransaction begins a new transaction
BeginTransaction() (Query, error)
// Commit commits the changes in a transaction.
Commit() error
// Context gets the context used by the query.
Context() context.Context
// Count retrieve the "count" result of the query.
Count() (int64, error)
// Create inserts new record into the database.
Create(value any) error
// Cursor returns a cursor, use scan to iterate over the returned rows.
Cursor() chan db.Row
// CursorPaginate fetches a single keyset ("seek") page and scans it into dest, returning the
// page and its cursors. It never counts, so the page carries no total, and the name is distinct
// from Cursor, which streams rows.
CursorPaginate(perPage int, cursor string, dest any) (db.CursorPaginator, error)
// DB gets the underlying database connection.
DB() (*sql.DB, error)
// Delete deletes records matching given conditions, if the conditions are empty will delete all records.
Delete(value ...any) (*db.Result, error)
// Distinct preserves the selected fields and returns distinct results. Optional columns
// specify DISTINCT ON in PostgreSQL and the distinct columns for aggregate queries.
Distinct(columns ...string) Query
// Driver gets the driver for the query.
Driver() string
// Exec executes raw sql
Exec(sql string, values ...any) (*db.Result, error)
// Exists returns true if matching records exist; otherwise, it returns false.
Exists() (bool, error)
// Find finds records that match given conditions.
Find(dest any, conds ...any) error
// FindOr finds the first record matching the given id, or runs the callback when there is none.
FindOr(dest any, id any, callback func() error) error
// FindOrFail finds records that match given conditions or throws an error.
FindOrFail(dest any, conds ...any) error
// First finds record that match given conditions.
First(dest any) error
// FirstOr finds the first record that matches the given conditions or
// execute the callback and return its result if no record is found.
FirstOr(dest any, callback func() error) error
// FirstOrCreate finds the first record that matches the given attributes
// or create a new one with those attributes if none was found.
FirstOrCreate(dest any, conds ...any) error
// FirstOrFail finds the first record that matches the given conditions or throws an error.
FirstOrFail(dest any) error
// FirstOrNew finds the first record that matches the given conditions or
// return a new instance of the model initialized with those attributes.
FirstOrNew(dest any, attributes any, values ...any) error
// FindMany retrieves the rows whose primary key is one of ids into dest, mirroring Laravel's
// Builder::findMany: an empty list reads nothing and leaves dest empty.
FindMany(dest any, ids []any, columns ...any) error
// ForceDelete forces delete records matching given conditions.
ForceDelete(value ...any) (*db.Result, error)
// Get retrieves all rows from the database. A column list may be given for this call only,
// mirroring Laravel's Builder::get($columns); the query's own selection is left untouched.
Get(dest any, columns ...any) error
// Group specifies the group method on the query.
// DEPRECATED Use GroupBy instead.
Group(column string) Query
// GroupBy specifies the group method on the query.
GroupBy(column ...string) Query
// Having specifying HAVING conditions for the query.
Having(query any, args ...any) Query
// InRandomOrder specifies the order randomly.
InRandomOrder() Query
// InTransaction checks if the query is in a transaction.
InTransaction() bool
// Join specifying JOIN conditions for the query.
Join(query string, args ...any) Query
// Limit the number of records returned.
Limit(limit int) Query
// Load loads a relationship for the model. args may be a callback or other
// shapes accepted by With (e.g. "Books:id,name" column pruning is supported by
// embedding the column list in relation; a callback may be passed via args).
Load(dest any, relation string, args ...any) error
// LoadMissing loads a relationship for the model that is not already loaded.
// args follow the same shapes as Load.
LoadMissing(dest any, relation string, args ...any) error
// LockForUpdate locks the selected rows in the table for updating.
LockForUpdate() Query
// Model sets the model instance to be queried.
Model(value any) Query
// OfMany configures a HasOne or MorphOne relation to return the row whose value of column
// matches the given SQL aggregate ("MAX" / "MIN") within each parent. Intended for use
// inside a With(...) callback so the rewrite is local to a single relation:
//
// q.With("LatestImage", func(q orm.Query) orm.Query {
// return q.OfMany("created_at", "MAX")
// })
OfMany(column, aggregate string) Query
// LatestOfMany is shorthand for OfMany(column, "MAX") with column defaulting to "id" when
// empty. Mirrors fedaco's latestOfMany().
LatestOfMany(column ...string) Query
// OldestOfMany is shorthand for OfMany(column, "MIN") with column defaulting to "id" when
// empty. Mirrors fedaco's oldestOfMany().
OldestOfMany(column ...string) Query
// Offset specifies the number of records to skip before starting to return the records.
Offset(offset int) Query
// Omit specifies columns that should be omitted from the query.
Omit(columns ...string) Query
// Order specifies the order in which the results should be returned.
// DEPRECATED Use OrderByRaw instead.
Order(value any) Query
// OrderBy specifies the order should be ascending.
OrderBy(column string, direction ...string) Query
// OrderByDesc specifies the order should be descending.
OrderByDesc(column string) Query
// OrderByRaw specifies the order should be raw.
OrderByRaw(raw string) Query
// Latest orders by the given column descending, defaulting to the model's created-at column,
// mirroring Laravel's Builder::latest.
Latest(column ...string) Query
// Oldest orders by the given column ascending, defaulting to the model's created-at column,
// mirroring Laravel's Builder::oldest.
Oldest(column ...string) Query
// OrWhere add an "or where" clause to the query.
OrWhere(query any, args ...any) Query
// OrWhereBetween adds an "or where column between x and y" clause to the query.
OrWhereBetween(column string, x, y any) Query
// OrWhereIn adds an "or where column in" clause to the query.
OrWhereIn(column string, values []any) Query
// OrWhereJsonContains adds an "or where JSON contains" clause to the query.
OrWhereJsonContains(column string, value any) Query
// OrWhereJsonContainsKey add a clause that determines if a JSON path exists to the query.
OrWhereJsonContainsKey(column string) Query
// OrWhereJsonDoesntContain add an "or where JSON not contains" clause to the query.
OrWhereJsonDoesntContain(column string, value any) Query
// OrWhereJsonDoesntContainKey add a clause that determines if a JSON path does not exist to the query.
OrWhereJsonDoesntContainKey(column string) Query
// OrWhereJsonLength add an "or where JSON length" clause to the query. Mirrors
// Laravel's Builder::orWhereJsonLength, so args is either (length) for an
// equality check or (operator, length) for a comparison.
OrWhereJsonLength(column string, args ...any) Query
// OrWhereNotBetween adds an "or where column not between x and y" clause to the query.
OrWhereNotBetween(column string, x, y any) Query
// OrWhereNotIn adds an "or where column not in" clause to the query.
OrWhereNotIn(column string, values []any) Query
// OrWhereNull adds a "or where column is null" clause to the query.
OrWhereNull(column string) Query
// Paginate the given query into a simple paginator.
Paginate(page, limit int, dest any, total *int64) error
// Pluck retrieves a single column from the database.
Pluck(column string, dest any) error
// Sole retrieves the one row the query matches, mirroring Laravel's Builder::sole: no row is an
// error, and so is more than one.
Sole(dest any) error
// Raw creates a raw query.
Raw(sql string, values ...any) Query
// Restore restores a soft deleted model.
Restore(model ...any) (*db.Result, error)
// Rollback rolls back the changes in a transaction.
Rollback() error
// Save updates value in a database
Save(value any) error
// SaveQuietly updates value in a database without firing events
SaveQuietly(value any) error
// Scan scans the query result and populates the destination object.
Scan(dest any) error
// Scopes applies one or more query scopes.
Scopes(funcs ...func(Query) Query) Query
// Select specifies fields that should be retrieved from the database.
Select(columns ...string) Query
// SelectRaw specifies a raw SQL query for selecting fields.
SelectRaw(query any, args ...any) Query
SharedLock() Query
// Sum calculates the sum of a column's values and populates the destination object.
Sum(column string, dest any) error
// Avg calculates the average of a column's values.
Avg(column string, dest any) error
// Min calculates the minimum value of a column.
Min(column string, dest any) error
// Max calculates the maximum value of a column.
Max(column string, dest any) error
// Increment adds amount (default 1) to the column of every matching row, refreshing the model's
// updated-at column and writing extra, mirroring Laravel's Builder::increment.
Increment(column string, args ...any) (*db.Result, error)
// Decrement subtracts amount (default 1) from the column of every matching row, refreshing the
// model's updated-at column and writing extra, mirroring Laravel's Builder::decrement.
Decrement(column string, args ...any) (*db.Result, error)
// Touch sets the model's updated-at column (or the named column) to now on every matching row,
// mirroring Laravel's Builder::touch. A model without an updated-at column touches nothing.
Touch(column ...string) (*db.Result, error)
// Table specifies the table for the query.
//
// A string is a bare table name, and the connection prefix is applied to it when the statement
// is rendered. Pass a query.Raw expression to name a table that is already qualified — for
// example a catalog name that must be addressed verbatim — and it is rendered as given, with no
// prefix added. That mirrors Laravel's withoutTablePrefix(), which the query builder itself does
// not expose.
Table(name any, args ...any) Query
// ToSql returns the query as a SQL string.
ToSql() ToSql
// ToRawSql returns the query as a raw SQL string.
ToRawSql() ToSql
// Update updates records with the given column and values
Update(column any, value ...any) (*db.Result, error)
// UpdateOrCreate finds the first record that matches the given attributes
// or create a new one with those attributes if none was found.
UpdateOrCreate(dest any, attributes any, values any) error
// Upsert inserts the rows, updating the listed columns of a row whose uniqueBy columns already
// exist. It mirrors Laravel's Builder::upsert on a model: the model's timestamps are stamped,
// the created-at column is left alone on update, and the updated-at column is always refreshed.
// With no update columns every inserted column is updated; an empty update list inserts only.
Upsert(values any, uniqueBy []string, update ...any) (*db.Result, error)
// Value retrieves a single column of the first row into dest, mirroring Laravel's
// Builder::value.
Value(column string, dest any) error
// UseWritePdo forces the query's reads to run on the write connection rather than the reader
// replica. Mirrors Laravel's Builder::useWritePdo.
UseWritePdo() Query
// When executes the callback if the condition is true, otherwise the falseCallback if it is given.
When(condition bool, callback func(query Query) Query, falseCallback ...func(query Query) Query) Query
// Where add a "where" clause to the query.
Where(query any, args ...any) Query
// WhereAll adds a "where all columns match" clause to the query.
WhereAll(columns []string, args ...any) Query
// WhereAny adds a "where any of columns match" clause to the query.
WhereAny(columns []string, args ...any) Query
// WhereBetween adds a "where column between x and y" clause to the query.
WhereBetween(column string, x, y any) Query
// WhereIn adds a "where column in" clause to the query.
WhereIn(column string, values []any) Query
// WhereJsonContains add a "where JSON contains" clause to the query.
WhereJsonContains(column string, value any) Query
// WhereJsonContainsKey add a clause that determines if a JSON path exists to the query.
WhereJsonContainsKey(column string) Query
// WhereJsonDoesntContain add a "where JSON not contains" clause to the query.
WhereJsonDoesntContain(column string, value any) Query
// WhereJsonDoesntContainKey add a clause that determines if a JSON path does not exist to the query.
WhereJsonDoesntContainKey(column string) Query
// WhereJsonLength add a "where JSON length" clause to the query. Mirrors
// Laravel's Builder::whereJsonLength, so args is either (length) for an
// equality check or (operator, length) for a comparison.
WhereJsonLength(column string, args ...any) Query
// WhereNone adds a "where none of columns match" clause to the query.
WhereNone(columns []string, args ...any) Query
// WhereNotBetween adds a "where column not between x and y" clause to the query.
WhereNotBetween(column string, x, y any) Query
// WhereNotIn adds a "where column not in" clause to the query.
WhereNotIn(column string, values []any) Query
// WhereNotNull adds a "where column is not null" clause to the query.
WhereNotNull(column string) Query
// WhereNull adds a "where column is null" clause to the query.
WhereNull(column string) Query
// WhereKey constrains the query to the row (or rows) with the given primary key, mirroring
// Laravel's Builder::whereKey. A slice stands for several keys; a model stands for its own key.
WhereKey(id any) Query
// WhereKeyNot excludes the row (or rows) with the given primary key, mirroring Laravel's
// Builder::whereKeyNot.
WhereKeyNot(id any) Query
// Except excludes the given models by primary key, mirroring Laravel's Builder::except.
Except(models any) Query
// WithAttributes adds the attributes as where equalities and remembers them for every model the
// query creates afterwards, mirroring Laravel's Builder::withAttributes. Pass a map, or a column
// with its value. asConditions false records the attributes without adding the where clauses.
WithAttributes(attributes any, args ...any) Query
// WithoutEvents disables event firing for the query.
WithoutEvents() Query
// WithoutGlobalScopes disables all global scopes for the query.
WithoutGlobalScopes(names ...string) Query
// Without removes the given relations from the eager-load list set by With.
// Mirrors fedaco's without().
Without(relations ...string) Query
// WithTrashed allows soft deleted models to be included in the results.
WithTrashed() Query
// OnlyTrashed restricts the results to the soft deleted models, mirroring Laravel's
// SoftDeletes::onlyTrashed: the automatic "not deleted" predicate is dropped and replaced by a
// "deleted_at is not null" one.
OnlyTrashed() Query
// With eagerly loads the given relationships using Goravel's own loader (does not
// delegate to GORM Preload). Accepts the union of fedaco's with(...) shapes:
//
// q.With("Books")
// q.With("Books", cb) // string + callback
// q.With("Books", "Roles", "Address") // multiple strings
// q.With("Books:id,name") // column pruning
// q.With(map[string]orm.RelationCallback{"Books": cb}) // map of name -> callback
// q.With([]any{"Books", map[string]orm.RelationCallback{"Roles": cb}})
// q.With("Books.Author") // nested
// q.With("Books.Author", cb) // nested + callback
//
// Supports HasOne, HasMany, BelongsTo, BelongsToMany, MorphOne, MorphMany,
// HasOneThrough and HasManyThrough.
With(args ...any) Query
// WithOnly clears the eager-load list set by With, then adds the given
// relations. Mirrors fedaco's withOnly().
WithOnly(args ...any) Query
}
type QueryWithClone ¶
type QueryWithClone interface {
Clone() Query
}
QueryWithClone is the optional capability a Query implements when it can hand out an independent copy. Orm.Query() uses it to return a new builder per call, which is what the Query() contract promises and what Laravel's Connection::query() does. A Query without it is returned as stored.
type QueryWithContext ¶
type QueryWithObserver ¶
type QueryWithRelations ¶
type QueryWithRelations interface {
// Has adds a relationship count / exists condition to the query.
// Defaults to operator ">=" and count 1.
Has(relation string, args ...any) Query
// OrHas adds a relationship count / exists condition to the query with an "or" conjunction.
OrHas(relation string, args ...any) Query
// DoesntHave adds a relationship absence condition - equivalent to Has(rel, "<", 1).
DoesntHave(relation string, args ...any) Query
// OrDoesntHave adds a relationship absence condition with an "or" conjunction.
OrDoesntHave(relation string, args ...any) Query
// WhereHas adds a relationship count / exists condition to the query with where clauses.
// Identical semantics to Has but conventionally used with a callback first arg.
WhereHas(relation string, args ...any) Query
// OrWhereHas adds a relationship count / exists condition to the query with where clauses
// and an "or" conjunction.
OrWhereHas(relation string, args ...any) Query
// WhereDoesntHave adds a relationship absence condition to the query with where clauses.
WhereDoesntHave(relation string, args ...any) Query
// OrWhereDoesntHave adds a relationship absence condition to the query with where clauses
// and an "or" conjunction.
OrWhereDoesntHave(relation string, args ...any) Query
// HasMorph adds a polymorphic relationship count / exists condition to the query.
// types is a slice of model instances (e.g. []any{&Post{}, &Video{}}); the morph value
// used in the type column is derived from each model's table name.
//
// Note: auto-discovery of distinct morph values via `types = ['*']` is not supported.
// An explicit list of model instances is required.
HasMorph(relation string, types []any, args ...any) Query
// OrHasMorph adds a polymorphic relationship count / exists condition with an "or" conjunction.
OrHasMorph(relation string, types []any, args ...any) Query
// DoesntHaveMorph adds a polymorphic relationship absence condition.
DoesntHaveMorph(relation string, types []any, args ...any) Query
// OrDoesntHaveMorph adds a polymorphic relationship absence condition with an "or" conjunction.
OrDoesntHaveMorph(relation string, types []any, args ...any) Query
// WhereHasMorph adds a polymorphic relationship count / exists condition to the query with
// where clauses. Callbacks may be MorphRelationCallback for per-type scoping.
WhereHasMorph(relation string, types []any, args ...any) Query
// OrWhereHasMorph adds a polymorphic relationship count / exists condition with where clauses
// and an "or" conjunction.
OrWhereHasMorph(relation string, types []any, args ...any) Query
// WhereDoesntHaveMorph adds a polymorphic relationship absence condition with where clauses.
WhereDoesntHaveMorph(relation string, types []any, args ...any) Query
// OrWhereDoesntHaveMorph adds a polymorphic relationship absence condition with where clauses
// and an "or" conjunction.
OrWhereDoesntHaveMorph(relation string, types []any, args ...any) Query
// WithAggregate adds a sub-select query to include an aggregate value for a relationship.
// fn must be one of: count, max, min, sum, avg, exists.
WithAggregate(relation, column, fn string, args ...any) Query
// WithCount adds sub-select queries to count the relations. Each entry may be either a
// string ("Books") or a RelationCount struct for scoped/aliased counts.
WithCount(relations ...any) Query
// WithMax adds sub-select queries to include the max of the relation's column.
WithMax(relation, column string, args ...any) Query
// WithMin adds sub-select queries to include the min of the relation's column.
WithMin(relation, column string, args ...any) Query
// WithSum adds sub-select queries to include the sum of the relation's column.
WithSum(relation, column string, args ...any) Query
// WithAvg adds sub-select queries to include the average of the relation's column.
WithAvg(relation, column string, args ...any) Query
// WithExists adds sub-select queries to include the existence of related models. The result
// is emitted as `CASE WHEN EXISTS (...) THEN 1 ELSE 0 END` for cross-dialect portability
// (SQL Server has no boolean literal), but the dest field may be either `bool` or an integer
// type - Go's database/sql layer converts 0/1 ints to bool automatically.
WithExists(relations ...string) Query
// WhereRelation adds a relationship existence condition with a single where on the related
// rows, mirroring Laravel's whereRelation: WhereRelation("Books", "title", "Go") is
// WhereHas("Books", func(q) { q.Where("title", "Go") }). A callback may be given in place of
// the column to constrain the related rows freely.
WhereRelation(relation string, column any, args ...any) Query
// OrWhereRelation is WhereRelation with an "or" conjunction.
OrWhereRelation(relation string, column any, args ...any) Query
// WhereDoesntHaveRelation adds a relationship absence condition with a single where on the
// related rows, mirroring Laravel's whereDoesntHaveRelation.
WhereDoesntHaveRelation(relation string, column any, args ...any) Query
// OrWhereDoesntHaveRelation is WhereDoesntHaveRelation with an "or" conjunction.
OrWhereDoesntHaveRelation(relation string, column any, args ...any) Query
// WithWhereHas constrains the query by the relation and eager loads it with the same
// constraint, mirroring Laravel's withWhereHas.
WithWhereHas(relation string, args ...any) Query
// WhereBelongsTo constrains the query to the rows that belong to the given model (or models),
// mirroring Laravel's whereBelongsTo: the parent's foreign key is matched against the related
// models' keys. The relation defaults to the related model's type name.
WhereBelongsTo(related any, relation ...string) Query
// OrWhereBelongsTo is WhereBelongsTo with an "or" conjunction.
OrWhereBelongsTo(related any, relation ...string) Query
}
QueryWithRelations is the Go port of the QueriesRelationships mixin from Laravel and the 1:1 TypeScript port in fedaco at libs/fedaco/src/fedaco/mixins/queries-relationships.ts.
Where the upstream framework has first-class Relation objects with getRelationExistenceQuery methods, GORM models its relationships through struct-tag metadata. The bridge here surfaces relationship-existence and aggregate-subselect queries on top of that metadata. Callers can write, for example:
users := []User{}
query.Query().Has("Books", ">=", 3).WithCount("Roles").Get(&users)
Existence-style methods (Has / OrHas / DoesntHave / WhereHas / ...) accept a variadic args slice that may carry, in any order:
- a RelationCallback or func(Query) Query to scope the inner subquery
- a string operator (e.g. ">=", "<", ">", "=") - defaults to ">="
- an int count - defaults to 1
Morph-style methods take an additional types []any of model instances; the morph value used in the type column is derived from each model's GORM-resolved table name (e.g. *User -> "users").
QueryWithRelations is embedded into Query, so all of these methods are also reachable directly off Query without a type assertion.
type Relation ¶
type Relation interface {
// Kind returns the relation flavour for diagnostics (error messages, logging). The resolver
// itself dispatches by Go type, not by the Kind value.
Kind() RelationKind
}
Relation is the sealed interface implemented by every per-kind relation declaration struct (HasOne, HasMany, BelongsTo, Many2Many, MorphOne, MorphMany, MorphTo, MorphToMany, MorphedByMany, HasOneThrough, HasManyThrough). The relation() method is unexported so external packages cannot define new kinds — the resolver type-switches on the closed set defined here.
Models declare their relationships in a single map:
func (User) Relations() map[string]orm.Relation {
return map[string]orm.Relation{
"Books": orm.HasMany{Related: &Book{}},
"Roles": orm.Many2Many{Related: &Role{}, Table: "user_roles"},
"Houses": orm.MorphMany{Related: &House{}, Name: "houseable"},
"Posts": orm.HasManyThrough{Related: &Post{}, Through: &Account{}},
}
}
All relation fields on the model struct must be tagged `gorm:"-"` so GORM doesn't try to auto-resolve them from struct tags.
type RelationCallback ¶
RelationCallback is the signature of a closure used to scope a relationship existence query. Mirrors the (q) => void closure shape from the QueriesRelationships mixin. The returned Query is the inner subquery used for has / whereHas / withCount / etc.
type RelationCount ¶
type RelationCount struct {
// Name is the relation method/field name on the parent model (e.g. "Books").
Name string
// Alias overrides the default `<relation>_count` column alias when non-empty.
Alias string
// Callback scopes the inner count subquery, mirroring the upstream array-keyed callback shape.
Callback RelationCallback
}
RelationCount is an entry accepted by WithCount that pairs a relation name with an optional scope callback and result alias. Equivalent to the array-keyed `withCount(['posts as p_count' => fn ...])` idiom in Laravel, expressed as a Go struct:
q.WithCount(orm.RelationCount{Name: "Books", Alias: "book_total", Callback: func(q) q.Where(...)})
type RelationKind ¶
type RelationKind string
RelationKind names a relationship flavour for diagnostic / error-message use only. The per-kind structs below (HasOne, HasMany, ...) are the actual user-facing declaration types; the RelationKind constants exist purely so error messages can refer to a kind by name.
const ( KindHasOne RelationKind = "hasOne" KindHasMany RelationKind = "hasMany" KindBelongsTo RelationKind = "belongsTo" KindMany2Many RelationKind = "many2Many" KindMorphOne RelationKind = "morphOne" KindMorphMany RelationKind = "morphMany" KindMorphTo RelationKind = "morphTo" KindMorphToMany RelationKind = "morphToMany" KindMorphedByMany RelationKind = "morphedByMany" KindHasOneThrough RelationKind = "hasOneThrough" KindHasManyThrough RelationKind = "hasManyThrough" )
type RelationWriter ¶
type RelationWriter interface {
// Save inserts or updates child as a member of the relation. Sets child's foreign key (and
// morph_type for MorphOne/MorphMany) from parent's local key, then persists child.
// Supported kinds: HasOne, HasMany, MorphOne, MorphMany, Many2Many, MorphToMany.
Save(child any) error
// SaveMany is the slice form of Save. children must be a slice or pointer-to-slice.
SaveMany(children any) error
// SaveWithPivot is Save with caller-supplied pivot column values for BelongsToMany kinds.
// On HasOneOrMany kinds attrs is ignored (no pivot row).
SaveWithPivot(child any, attrs map[string]any) error
// SaveManyWithPivot is the slice form of SaveWithPivot. attrsPerChild is keyed by the related
// PK of each child; an entry may be nil to attach without extra columns.
SaveManyWithPivot(children any, attrsPerChild map[any]map[string]any) error
// Create persists a new related row. For HasOneOrMany kinds the framework pre-sets FK (and
// morph type) on dest from parent, then inserts. For BelongsToMany kinds inserts dest first,
// then writes a pivot row.
Create(dest any) error
// CreateMany is the slice form of Create.
CreateMany(dests any) error
// FindOrNew finds the related row with primary key id. If absent, fills dest with a new
// instance of the related model and pre-sets FK (and morph type) — does NOT persist.
FindOrNew(id any, dest any) error
// FirstOrNew finds the first related row matching attrs. If absent, fills dest with a new
// instance carrying attrs+values and pre-set FK — does NOT persist.
FirstOrNew(attrs, values map[string]any, dest any) error
// FirstOrCreate is FirstOrNew that persists when no matching row exists. For BelongsToMany
// kinds also writes a pivot row.
FirstOrCreate(attrs, values map[string]any, dest any) error
// UpdateOrCreate finds the first related row matching attrs (or creates one), then overlays
// values onto it and persists. For BelongsToMany kinds also writes a pivot row when freshly
// created. Always saves dest.
UpdateOrCreate(attrs, values map[string]any, dest any) error
// Associate sets parent's foreign key (and morph_type for MorphTo) to point at owner, then
// persists parent. Supported kinds: BelongsTo, MorphTo. owner must be a non-nil pointer to a
// struct.
Associate(owner any) error
// Dissociate clears parent's foreign key (and morph_type for MorphTo) and persists parent.
// Supported kinds: BelongsTo, MorphTo.
Dissociate() error
// Attach inserts pivot rows linking parent to each id in ids. For polymorphic pivots the
// morph_type column is filled from the parent's morph value. Skips ids that already have a
// pivot row. Supported kinds: Many2Many, MorphToMany, MorphedByMany.
Attach(ids []any) error
// AttachWithPivot is Attach with per-row pivot column values. The map key is the related id;
// the map value is the column-name-to-value map applied to that pivot row.
AttachWithPivot(idsWithAttrs map[any]map[string]any) error
// Detach removes pivot rows linking parent to the given ids. With nil ids, removes all pivot
// rows for parent (and morph type, for polymorphic). Returns the number of rows removed.
Detach(ids ...any) (int64, error)
// Sync replaces parent's pivot rows so they exactly match ids: detaches missing entries,
// attaches new ones, leaves existing untouched.
Sync(ids []any) (*db.SyncResult, error)
// SyncWithPivot is Sync with per-ID pivot column values. The map key is the related id; the
// map value is the column-name-to-value map applied to that pivot row. For existing pivot
// rows with non-empty attrs, updates the pivot columns (reported in SyncResult.Updated).
SyncWithPivot(idsWithAttrs map[any]map[string]any) (*db.SyncResult, error)
// SyncWithPivotValues is a convenience wrapper that applies the same pivot column values to
// all ids.
SyncWithPivotValues(ids []any, pivotValues map[string]any) (*db.SyncResult, error)
// SyncWithoutDetaching is Sync minus the detach step — adds missing entries only.
SyncWithoutDetaching(ids []any) (*db.SyncResult, error)
// SyncWithoutDetachingWithPivot is SyncWithPivot minus the detach step.
SyncWithoutDetachingWithPivot(idsWithAttrs map[any]map[string]any) (*db.SyncResult, error)
// Toggle attaches missing entries and detaches existing ones.
Toggle(ids []any) (*db.SyncResult, error)
// ToggleWithPivot is Toggle with per-ID pivot column values for newly attached rows.
ToggleWithPivot(idsWithAttrs map[any]map[string]any) (*db.SyncResult, error)
// UpdateExistingPivot updates pivot columns for an already-attached id.
UpdateExistingPivot(id any, attrs map[string]any) (int64, error)
}
RelationWriter is the write-side builder for a single (parent, relation) pair, returned by Query.Relation / Orm.Relation. All write operations on a relation flow through this interface; flat methods like Orm.Save(parent, relation, child) intentionally do not exist.
RelationWriter has NO Where / OrderBy / chain methods — fedaco-style "where(...).updateOrCreate(...)" composition is not supported because Goravel's relation system is metadata-driven (declared via ModelWithRelations.Relations()), not method-driven. Search criteria for the find-then-write methods (FirstOrNew/FirstOrCreate/UpdateOrCreate/FindOrNew) are passed via the attrs map, which is combined with the relation's foreign-key scope.
For chained reads on a relation, use Query.Related(parent, name) instead — it returns a regular Query already scoped by the relation's foreign key, supporting the full Where/OrderBy/Get chain.
type ToSql ¶
type ToSql interface {
Count() string
Create(value any) string
Delete(value ...any) string
Find(dest any, conds ...any) string
First(dest any) string
ForceDelete(value ...any) string
Get(dest any) string
Pluck(column string, dest any) string
Save(value any) string
Sum(column string, dest any) string
Update(column any, value ...any) string
}