Documentation
¶
Index ¶
- type BelongsTo
- type BelongsToManyRelation
- type BelongsToRelation
- type DispatchesEvents
- type Event
- type EventType
- type Factory
- type GlobalScope
- type HasMany
- type HasManyRelation
- type HasManyThrough
- type HasManyThroughRelation
- type HasOne
- type HasOneOrManyRelation
- type HasOneRelation
- type HasOneThrough
- type HasOneThroughRelation
- type Many2Many
- type Many2ManyRelation
- type ModelToObserver
- type ModelWithConnection
- type ModelWithGlobalScopes
- type ModelWithMorphClass
- type ModelWithRelations
- type ModelWithTableName
- type ModelWithTimestamps
- type MorphMany
- type MorphManyRelation
- type MorphOne
- type MorphOneRelation
- type MorphRelationCallback
- type MorphTo
- type MorphToMany
- type MorphToManyRelation
- type MorphToRelation
- type MorphedByMany
- type MorphedByManyRelation
- type Observer
- type ObserverWithCreating
- type ObserverWithDeleting
- type ObserverWithForceDeleting
- type ObserverWithRestored
- type ObserverWithRestoring
- type ObserverWithRetrieved
- type ObserverWithSaved
- type ObserverWithSaving
- type ObserverWithUpdating
- type OfManyColumn
- type Orm
- type PivotCallback
- type PivotFactory
- type PivotKeyed
- type PivotModel
- type PivotQuery
- type Query
- type QueryWithClone
- type QueryWithContext
- type QueryWithInverseChaperone
- type QueryWithObserver
- type QueryWithRelations
- type Relation
- type RelationCallback
- type RelationCount
- type RelationKind
- type RelationQuery
- type RelationWriterdeprecated
- 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
// WithDefault — the BelongsTo form of HasOne.WithDefault. The default instance is a plain
// newInstance of the related model with no attributes set (BelongsTo::newRelatedInstanceFor),
// and it also stands in when the parent's foreign key is null (getResults' is_null
// short-circuit).
WithDefault any
// Touches, when true, makes saving or deleting the declaring model touch the rows this
// relation resolves to — their updated-at column is stamped, and the loaded related models'
// own Touches declarations carry the propagation onward — mirroring an entry in Eloquent's
// `protected $touches` array and the HasRelationships::touchOwners walk behind it. The stamp
// itself is skipped while the related model's class is in a withoutTouching ignore list
// (Model::isIgnoringTouch), while the walk still resolves the related models — reusing the
// relation the model already carries loaded, or lazy-loading and caching it — and continues
// through them either way. Declared on the BelongsTo / HasOne / HasMany kinds the corpus's
// touching family exercises.
Touches bool
}
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 BelongsToManyRelation ¶
type BelongsToManyRelation interface {
RelationQuery
// FindOrNew finds the related row with primary key id; on a miss it fills dest with a new
// instance of the related model. Nothing is written on the miss.
FindOrNew(id any, dest any) error
// FindSole returns the attached related row with primary key id, erroring when no row matches
// and when several do — Laravel BelongsToMany::findSole (BelongsToMany.php:750-757,
// `$this->where($this->getRelated()->getQualifiedKeyName(), '=', $this->parseId($id))->sole($columns)`).
// The Go form composes WhereKey(id)->Sole(dest) over the relation's pivot-aware read; oracle
// v12.55.1, executed (/tmp/lalign-probes/accessors.php): the statement carries the pivot
// aliases and `... and "lax_roles"."id" = ? limit 2`; a missing id throws
// ModelNotFoundException (the Go read reports errors.OrmRecordNotFound); a model argument
// stands for its own key.
FindSole(id any, dest any) error
// FirstWhere adds the where clause and returns the first matching row into dest — Laravel
// BelongsToMany::firstWhere (BelongsToMany.php:853-856,
// `$this->where($column, $operator, $value, $boolean)->first()`); a miss leaves dest empty and
// reports no error. Oracle: `... and "name" = ? limit 1`; a miss returns null.
FirstWhere(dest any, column any, args ...any) error
// FirstOrNew — see HasOneOrManyRelation.FirstOrNew. The signature mirrors Query.FirstOrNew.
FirstOrNew(dest any, attributes any, values ...any) error
// FirstOrCreate — see HasOneOrManyRelation.FirstOrCreate; on a fresh create a pivot row is
// written too. The signature mirrors Query.FirstOrCreate.
FirstOrCreate(dest any, conds ...any) error
// UpdateOrCreate — Laravel BelongsToMany::updateOrCreate (BelongsToMany.php:707): FirstOrCreate's
// three-level search — an attached hit returns with its pivot, an unattached hit is attached,
// a miss is created and attached — followed by fill+save on every row that was not freshly
// created (wasRecentlyCreated false). The signature mirrors Query.UpdateOrCreate.
UpdateOrCreate(dest any, attributes any, values any) error
// CreateOrFirst — see HasOneOrManyRelation.CreateOrFirst. The signature mirrors
// Query.CreateOrFirst.
CreateOrFirst(dest any, conds ...any) error
// Save inserts or updates child as a member of the relation. Kind support matches
// RelationWriter.Save.
Save(child any) error
// SaveQuietly is Save with every model event suppressed — Laravel's BelongsToMany::saveQuietly
// (BelongsToMany.php:1366), save inside Model::withoutEvents (HasEvents.php:445). The oracle
// measured zero events on the quiet call while the related row and the pivot row still land
// and the model is returned; the pivot attach and the parent touch raise no model events on
// either path.
SaveQuietly(child any) error
// SaveMany is the slice form of Save.
SaveMany(children any) error
// SaveManyQuietly is the slice form of SaveQuietly — BelongsToMany::saveManyQuietly (:1402).
SaveManyQuietly(children any) error
// SaveWithPivot is Save with caller-supplied pivot column values.
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.
SaveManyWithPivot(children any, attrsPerChild map[any]map[string]any) error
// Create persists a new related row and the pivot row linking it to the parent.
Create(dest any) error
// CreateMany is the slice form of Create.
CreateMany(dests any) error
// Attach inserts pivot rows linking parent to each id, skipping ids already attached.
Attach(ids []any) error
// AttachOrFail is Attach inside a transaction on the parent's connection — IWPT::attachOrFail
// (InteractsWithPivotTable.php:365; a 12.55-only addition),
// $this->parent->getConnection()->transaction(fn () => $this->attach(...)). The oracle
// measured a begin+commit pair around the call and a begin+rollback pair when the insert
// fails.
AttachOrFail(ids []any) error
// AttachWithPivot is Attach with per-row pivot column values, keyed by the related id.
AttachWithPivot(idsWithAttrs map[any]map[string]any) error
// Detach removes the pivot rows for the given ids; nil ids remove every pivot row of the
// parent. It reports the removed row count.
Detach(ids ...any) (int64, error)
// DetachOrFail is Detach inside a parent-connection transaction — IWPT::detachOrFail (:562).
DetachOrFail(ids ...any) (int64, error)
// Sync replaces the parent's pivot rows so they exactly match ids.
Sync(ids []any) (*db.SyncResult, error)
// SyncOrFail is Sync inside a parent-connection transaction — IWPT::syncOrFail (:157).
SyncOrFail(ids []any) (*db.SyncResult, error)
// SyncWithPivot is Sync with per-ID pivot column values, keyed by the related id.
SyncWithPivot(idsWithAttrs map[any]map[string]any) (*db.SyncResult, error)
// SyncWithPivotValues applies the same pivot column values to every id.
SyncWithPivotValues(ids []any, pivotValues map[string]any) (*db.SyncResult, error)
// SyncWithPivotValuesOrFail is SyncWithPivotValues inside a parent-connection transaction —
// IWPT::syncWithPivotValuesOrFail (:200).
SyncWithPivotValuesOrFail(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)
// SyncWithoutDetachingOrFail is SyncWithoutDetaching inside a parent-connection transaction —
// IWPT::syncWithoutDetachingOrFail (:170), Laravel's syncOrFail($ids, false).
SyncWithoutDetachingOrFail(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)
// ToggleOrFail is Toggle inside a parent-connection transaction — IWPT::toggleOrFail (:75).
ToggleOrFail(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 the pivot columns of an already-attached id.
UpdateExistingPivot(id any, attrs map[string]any) (int64, error)
// UpdateExistingPivotOrFail is UpdateExistingPivot inside a parent-connection transaction —
// IWPT::updateExistingPivotOrFail (:299).
UpdateExistingPivotOrFail(id any, attrs map[string]any) (int64, error)
// AllRelatedIds collects the related ids into dest — a pointer to a slice — plucking the
// related pivot key, Eloquent's allRelatedIds.
AllRelatedIds(dest any) error
// WherePivot adds a "where" clause on the pivot table into dest-side queries; the column is
// qualified with the pivot table and args follow Query.Where. Mirrors BelongsToMany::wherePivot.
WherePivot(column any, args ...any) BelongsToManyRelation
// OrWherePivot is WherePivot with the "or" connector.
OrWherePivot(column any, args ...any) BelongsToManyRelation
// WherePivotIn adds a "where column in" clause on the pivot table.
WherePivotIn(column any, values []any) BelongsToManyRelation
// WherePivotNotIn adds a "where column not in" clause on the pivot table.
WherePivotNotIn(column any, values []any) BelongsToManyRelation
// OrWherePivotIn is WherePivotIn with the "or" connector.
OrWherePivotIn(column any, values []any) BelongsToManyRelation
// OrWherePivotNotIn is WherePivotNotIn with the "or" connector.
OrWherePivotNotIn(column any, values []any) BelongsToManyRelation
// WherePivotNull adds a "pivot column is null" clause.
WherePivotNull(column any) BelongsToManyRelation
// WherePivotNotNull adds a "pivot column is not null" clause.
WherePivotNotNull(column any) BelongsToManyRelation
// OrWherePivotNull is WherePivotNull with the "or" connector.
OrWherePivotNull(column any) BelongsToManyRelation
// OrWherePivotNotNull is WherePivotNotNull with the "or" connector.
OrWherePivotNotNull(column any) BelongsToManyRelation
// WherePivotBetween adds a "pivot column between x and y" clause.
WherePivotBetween(column any, x, y any) BelongsToManyRelation
// WherePivotNotBetween adds a "pivot column not between x and y" clause.
WherePivotNotBetween(column any, x, y any) BelongsToManyRelation
// OrWherePivotBetween is WherePivotBetween with the "or" connector.
OrWherePivotBetween(column any, x, y any) BelongsToManyRelation
// OrWherePivotNotBetween is WherePivotNotBetween with the "or" connector.
OrWherePivotNotBetween(column any, x, y any) BelongsToManyRelation
// WithPivotValue adds a "pivot column = value" clause and records the value for pivot
// writes, mirroring BelongsToMany::withPivotValue; a nil value pairs the column with the
// pivot's parent-side foreign key column — Laravel's argument swap.
WithPivotValue(column any, value any) BelongsToManyRelation
// OrderByPivot adds an "order by pivot column" clause. Mirrors BelongsToMany::orderByPivot;
// the Go object keeps the relation (PHP returns the builder), so further wherePivot calls
// stay on the object.
OrderByPivot(column any, direction ...string) BelongsToManyRelation
// OrderByPivotDesc adds a descending "order by pivot column" clause — BelongsToMany::orderByPivotDesc
// (vendor v12.55.1, BelongsToMany.php:605-608,
// `return $this->orderBy($this->qualifyPivotColumn($column), 'desc');`; 12.55-only — the
// v12.43.1 checkout has no Desc sibling, its orderByPivot ends at BelongsToMany.php:583-586).
// The Go form is the one-liner over OrderByPivot(column, "desc"): an Expression column and an
// invalid direction ride the exact paths OrderByPivot documents beneath it.
OrderByPivotDesc(column any) BelongsToManyRelation
// WithPivot registers pivot-table columns to retrieve with this relation's reads —
// InteractsWithPivotTable::withPivot (vendor v12.55.1, Concerns/InteractsWithPivotTable.php:702-707,
// `$this->pivotColumns = array_merge($this->pivotColumns, is_array($columns) ? $columns :
// func_get_args());`). Laravel merges the call-time list into $pivotColumns, which
// aliasedPivotColumns (:970-983) then appends to the relation read's select list as
// `qualifyPivotColumn($column).' as pivot_'.$column`, deduplicated with ->unique(). The Go form
// carries the call-time list on the object and feeds it to the read's select rewrite after the
// related model's declared PivotField-struct columns — the Go stand-in for the declaration-time
// half of the list (see Many2Many.PivotField). Oracle (v12.55.1, executed, sqlite;
// /tmp/lalign-probes/pivot_surface.out): P2 — `withPivot('level')` makes the get() statement
// carry `"lax_role_user"."level" as "pivot_level"` and the hydrated pivot report 'gold'; P3 —
// the raw list keeps duplicates (["level","level"]) while the SELECT deduplicates; P4 — chained
// calls append and the array form keeps its order; P7 — attach's insert and sync's pivot read
// never replay the list. An entry with no declared struct field is selected but not surfaced in
// Go (PHP hydrates it as a dynamic pivot attribute — the documented divergence), and the Go
// write shells resolve their own statements per call, so call-time entries cannot reach them
// either (the wherePivot-style frozen-shell divergence).
WithPivot(columns ...string) BelongsToManyRelation
// HasPivotColumn reports whether column was explicitly registered through WithPivot — IWPT
// ::hasPivotColumn (:508-510, `return in_array($column, $this->pivotColumns);`), the explicit
// list only: the default pivot keys are not members until passed to WithPivot themselves
// (oracle P1a false for both foreign keys; P9 true after `withPivot('lax_user_id')`), and the
// declared PivotField struct's columns are not either.
HasPivotColumn(column string) bool
// GetPivotColumns gets the explicit pivot-column list WithPivot accumulated —
// BelongsToMany::getPivotColumns (vendor v12.55.1, BelongsToMany.php:1689-1691,
// `return $this->pivotColumns;`). The raw merged list in call order: duplicates are kept
// (oracle P3) and nothing is filtered; nil before any WithPivot — the oracle's [] default
// (P1a). The returned slice is a fresh copy (PHP arrays return by value), so a caller mutating
// it cannot reach the relation.
GetPivotColumns() []string
// GetPivotAccessor gets the name the pivot hydration lands under — BelongsToMany
// ::getPivotAccessor (vendor v12.55.1, BelongsToMany.php:1679-1681, `return $this->accessor;`:
// the As override, else the class default 'pivot', BelongsToMany.php:145). The Go accessor is
// the name of the struct field the read hydrates on the related model — the declared
// PivotField (default "Pivot") or the As override — because a Go model carries its pivot in a
// declared field, not in a dynamic relation map; a projection that names no field reports "".
GetPivotAccessor() string
// As declares the name the pivot hydration lands under, replacing the relation's declared
// accessor — BelongsToMany::as (vendor v12.55.1, BelongsToMany.php:367-372,
// `$this->accessor = $accessor; return $this;`). In Go that name selects the struct field the
// read hydrates on the related model (the PivotField convention): As re-resolves the read's
// pivot plan against the field with that name — the same resolution the declaration performs,
// so a name the related model has no field for hydrates nothing while the read keeps its
// declared select list under the fixed pivot-key aliases (oracle P5: as('subscription') moves
// the hydrated pivot to
// $role->subscription and leaves $role->pivot null, and the SQL aliases stay pivot_-prefixed —
// the accessor never renames them). A field that exists but is not a struct reports the read's
// error (errors.OrmRelationPivotFieldNotStruct — the declaration-time typo error). An empty
// accessor restores the declared field. The list half is unaffected (oracle P5:
// getPivotColumns() unchanged under as()).
As(accessor string) BelongsToManyRelation
// Using records the pivot factory the relation's pivot-construction methods dispatch through —
// Laravel's BelongsToMany::using (vendor v12.55.1, BelongsToMany.php:350-355, `$this->using =
// $class; return $this;`) — the Go stand-in for the custom pivot class string, held per
// relation instance exactly as Laravel holds $using. nil clears it back to the default
// constructors. Oracle (v12.55.1, executed, /tmp/decide-light-using/using_probe.php): the
// default relation reports the class default Pivot, `using(LuRoleUser::class)` reports
// LuRoleUser (`U1a default getPivotClass => 'Illuminate\Database\Eloquent\Relations\Pivot'`,
// `U1c getPivotClass after using => 'LuRoleUser'`). getPivotClass itself and the class-string
// argument are deferred — Go has no class strings; the factory replaces the class.
Using(factory PivotFactory) BelongsToManyRelation
// NewPivot builds the pivot instance the relation's surfaces construct —
// InteractsWithPivotTable::newPivot (vendor v12.55.1, InteractsWithPivotTable.php:627-642):
// the Using factory is consulted when one is recorded (Laravel dispatches through
// Model::newPivot, Model.php:1726), else the relation builds the class default
// Pivot::fromAttributes; the finished pivot then carries the relation's pivot keys and the
// related model (setPivotKeys -> setRelatedModel, :640-642). Oracle (same probe): `U2a default
// newPivot class/exists => [Pivot, false]`, `U2a default newPivot table/keys => ['lu_role_user',
// 'lu_user_id', 'role_id']`, `U2c custom newPivot class/exists => ['LuRoleUser', false]`. The
// morph kinds override with MorphPivot and the morph stamps (MorphToMany::newPivot,
// MorphToMany.php:156). The withPivotValue-recorded values Laravel merges in (:629) have no Go
// consumer — the documented WithPivotValue divergence.
NewPivot(attributes map[string]any, exists bool) (PivotModel, error)
// NewExistingPivot is NewPivot with exists true — InteractsWithPivotTable::newExistingPivot
// (:646, `return $this->newPivot($attributes, true);`), the constructor the read path's
// BelongsToMany::hydratePivotRelation (BelongsToMany.php:1234) feeds migrated pivot attributes
// into (oracle: `U2b default newExistingPivot class/exists => [Pivot, true]`, `U2d custom
// newExistingPivot class/exists/dirty => [LuRoleUser, true, []]`).
NewExistingPivot(attributes map[string]any) (PivotModel, error)
}
BelongsToManyRelation is the write surface of the Many2Many / MorphToMany / MorphedByMany objects — Eloquent's BelongsToMany methods on the relation: the pivot write family, the pivot-column query family and the related-id list. The methods whose names also exist on Query (Save / Create / FirstOrNew / FirstOrCreate / UpdateOrCreate / CreateOrFirst) take the Query signature — see RelationQuery's shadowing rule.
type BelongsToRelation ¶
type BelongsToRelation interface {
RelationQuery
// Associate sets the parent's foreign key (and morph type, for MorphTo) to point at owner,
// then persists the parent. A nil owner clears the foreign key (and morph type) instead.
Associate(owner any) error
// Dissociate clears the parent's foreign key (and morph type) and persists the parent.
Dissociate() error
// Disassociate is the MorphTo spelling of Dissociate — Eloquent's MorphTo::disassociate.
Disassociate() error
// GetChild gets the child model that holds the foreign key — for a BelongsTo the parent the
// relation was resolved from, Eloquent's BelongsTo::getChild.
GetChild() any
// GetForeignKeyName gets the plain foreign key the child holds — BelongsTo::getForeignKeyName
// (BelongsTo.php:306, `return $this->foreignKey;`). Oracle v12.55.1, executed: $post->user()
// reports "lax_user_id"; the MorphTo form reports the morph id column ("commentable_id").
GetForeignKeyName() string
// GetQualifiedForeignKeyName gets the foreign key qualified with the child's own table —
// BelongsTo::getQualifiedForeignKeyName (BelongsTo.php:316,
// `$this->child->qualifyColumn(...)`). Oracle: "lax_posts.lax_user_id";
// "lax_comments.commentable_id" for MorphTo.
GetQualifiedForeignKeyName() string
// GetOwnerKeyName gets the related model's owner key — BelongsTo::getOwnerKeyName
// (BelongsTo.php:336, `return $this->ownerKey;`; MorphTo inherits it unchanged). Oracle: "id";
// "custom_key" for an explicit morphTo(..., 'custom_key'); null on the MorphTo eager form (the Go
// descriptor's build-time default reports "id" on an eager real descriptor; "" surfaces
// only for a projection that carries no owner key). The MorphTo descriptor pins the instance path's resolution
// (`$ownerKey ?? $instance->getKeyName()`, Concerns/HasRelationships.php:446-453) at build
// time — see MorphToRelation.MorphOwnerKey.
GetOwnerKeyName() string
// GetQualifiedOwnerKeyName gets the owner key qualified with the related table —
// BelongsTo::getQualifiedOwnerKeyName (BelongsTo.php:346), overridden by MorphTo
// (MorphTo.php:429-437) to report "" when the owner key is null (the oracle's eager form).
// Oracle: "lax_users.id".
GetQualifiedOwnerKeyName() string
// GetRelationName gets the declared relation name — BelongsTo::getRelationName
// (BelongsTo.php:380, `return $this->relationName;`; MorphTo passes the name through).
// Oracle: "user"; "commentable".
GetRelationName() string
// WithDefault overrides the relation's default related instance at call time — BelongsTo's
// SupportsDefaultModels::withDefault (BelongsTo.php:8 composes the trait, :78-85 getResults).
// The default instance is a plain newInstance of the related model with no attributes set
// (BelongsTo::newRelatedInstanceFor, :286), standing in on a missing row and on a null foreign
// key; MorphTo inherits the method through this interface (MorphTo extends BelongsTo in PHP).
// Oracle (v12.55.1, executed, /tmp/lalign-defaults-inverse/runtime_withdefault.php):
// belongsTo.missing-row.attributes [] and belongsTo.null-fk.attributes [].
WithDefault(value any) BelongsToRelation
}
BelongsToRelation is the write surface of the BelongsTo / MorphTo objects — Eloquent's BelongsTo methods on the relation.
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 GlobalScope ¶
GlobalScope is one global scope a model declares. Name identifies the scope — WithoutGlobalScopes takes the same names — and Scope constrains the query it is applied to.
type HasMany ¶
type HasMany struct {
Related any
ForeignKey string
LocalKey string
OnQuery RelationCallback
// Inverse — see HasOne.Inverse.
Inverse string
// Touches — see BelongsTo.Touches.
Touches bool
}
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 HasManyRelation ¶
type HasManyRelation interface {
HasOneOrManyRelation
// One narrows this relation to a HasOne relation — Laravel's HasMany::one() (and
// MorphMany::one(), which narrows to MorphOne).
One() HasOneRelation
}
HasManyRelation extends HasOneOrManyRelation with Eloquent's HasMany::one(): the relation narrowed to a single result. The narrowed object shares this object's builder and constraints; call One before the first builder chain.
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 HasManyThroughRelation ¶
type HasManyThroughRelation interface {
HasOneThroughRelation
// One narrows this relation to a HasOneThrough relation sharing this object's builder and
// constraints.
One() HasOneThroughRelation
}
HasManyThroughRelation extends HasOneThroughRelation with Eloquent's HasManyThrough::one().
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
// Inverse names a relation on the related model that every loader read of this relation fills
// with the parent instance — Laravel's ->inverse('user') / ->chaperone() on HasOne / HasMany /
// MorphOne / MorphMany. Lazy loads (Load / LoadMissing), eager loads (With and the parent
// collections it reads) and a read that falls back to the WithDefault instance all store the
// same parent — the Go form of assertSame($parent, $child->inverse) — with no extra query.
// The name must be declared in the related model's Relations() map; resolving this relation
// otherwise reports OrmRelationNotFound. Loading without the write-back is a relation declared
// without this field: the declaration is static metadata, so Laravel's per-call withoutInverse()
// reaches the same state one call earlier instead.
Inverse string
// WithDefault mirrors Laravel's withDefault(): a relation read that finds no related row —
// or whose parent local key is empty — loads a default related instance in place of nil.
// Accepted values:
//
// - true: a fresh instance of the related model with its foreign key pre-set to the
// parent's local-key value (HasOne::newRelatedInstanceFor).
// - map[string]any: the fresh instance, force-filled with the map's attributes; keys name
// the related model's columns. An empty map is falsy in Laravel's check, like
// withDefault([]), and yields no default.
// - func(related, parent any) any: the fresh instance and the actual parent model are
// passed to the callback. A PHP-truthy return replaces the instance; a PHP-falsy return
// — false, 0, 0.0, "", "0", an empty slice or map, nil — keeps it (Laravel's
// `call_user_func($callback, $instance, $parent) ?: $instance`).
//
// A related row, when one exists, always wins: the default only stands in where the read
// found nothing. false / nil mean no default. Defaults apply to Load / LoadMissing / With;
// the raw Related() relation query keeps returning no rows, exactly as
// `$parent->relation()->first()` does in Laravel.
WithDefault any
// Touches — see BelongsTo.Touches.
Touches bool
}
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 HasOneOrManyRelation ¶
type HasOneOrManyRelation interface {
RelationQuery
// Make builds an unsaved related model instance into dest: the given attributes (a
// map-shaped value, optional) merged over the query's pending attributes (WithAttributes),
// with the relation's foreign key (and morph type) pre-set — Eloquent's HasOneOrMany::make.
// Nothing is written. The signature mirrors Query.Make.
Make(dest any, attributes ...any) error
// MakeMany is the slice form of Make: one unsaved instance per record, in record order.
MakeMany(records []map[string]any, dests any) error
// Save inserts or updates child as a member of the relation: the foreign key (and morph
// type, for MorphOne/MorphMany) is set from the parent, then child is persisted. Kind
// support matches RelationWriter.Save.
Save(child any) error
// SaveMany is the slice form of Save.
SaveMany(children any) error
// Create persists a new related row from dest, pre-setting the foreign key (and morph type)
// from the parent, then inserts dest. Kind support matches RelationWriter.Create.
Create(dest any) error
// CreateMany is the slice form of Create.
CreateMany(dests any) error
// FindOrNew finds the related row with primary key id; on a miss it fills dest with a new
// instance of the related model, foreign key pre-set. Nothing is written on the miss.
FindOrNew(id any, dest any) error
// FirstOrNew finds the first related row matching the attributes; on a miss it fills dest
// with a new instance carrying the attributes (and values) and the pre-set foreign key
// (and morph type). Nothing is written. The signature mirrors Query.FirstOrNew: attributes
// is a map-shaped value and values a variadic list of maps.
FirstOrNew(dest any, attributes any, values ...any) error
// FirstOrCreate is FirstOrNew that persists on a miss. The signature mirrors
// Query.FirstOrCreate: conds carries the attribute and value maps.
FirstOrCreate(dest any, conds ...any) error
// UpdateOrCreate finds the first related row matching the attributes (or creates one), then
// overlays values onto it and persists. The signature mirrors Query.UpdateOrCreate.
UpdateOrCreate(dest any, attributes any, values any) error
// CreateOrFirst attempts the insert with the attributes (and values) immediately and, when
// the insert trips a unique constraint, reads the row matching the attributes back. The
// signature mirrors Query.CreateOrFirst.
CreateOrFirst(dest any, conds ...any) error
// Upsert merges the parent key (and morph type, for MorphOne/MorphMany) into every row and
// delegates to the query-level upsert. values is a []map[string]any, the shape
// Query.Upsert takes; the signature mirrors it.
Upsert(values any, uniqueBy []string, update ...any) (*db.Result, error)
// SaveQuietly is Save with every model event suppressed — Laravel's HasOneOrMany::saveQuietly
// (vendor v12.55.1, HasOneOrMany.php:345), which runs save inside Model::withoutEvents
// (Concerns/HasEvents.php:445, the NullDispatcher swap). The write is otherwise identical:
// the foreign key (and morph type) still stamps and the row still persists. The oracle
// (v12.55.1, executed) measured zero events on the quiet call against
// saving/creating/created/saved on the loud one, with byte-identical insert SQL. It shadows
// Query.SaveQuietly by design — same signature, relation semantics.
SaveQuietly(child any) error
// SaveManyQuietly is the slice form of SaveQuietly — HasOneOrMany::saveManyQuietly (:373).
SaveManyQuietly(children any) error
// CreateQuietly is Create with every model event suppressed — HasOneOrMany::createQuietly
// (:403). The oracle measured zero events with the row persisted and the foreign key set.
CreateQuietly(dest any) error
// CreateManyQuietly is the slice form of CreateQuietly — HasOneOrMany::createManyQuietly
// (:455).
CreateManyQuietly(dests any) error
// ForceCreate persists a new related row without the mass-assignment guard —
// HasOneOrMany::forceCreate (:414), overridden by MorphOneOrMany::forceCreate (:78) and
// MorphMany::forceCreate (:63) to stamp the morph type. The Go create path applies no guard
// and already stamps the morph type, so this is the 1:1 alias of Create; the oracle measured
// forceCreate firing the same saving/creating/created/saved events with the foreign key set,
// a guarded attribute written where create silently discards it, and a pending
// WithAttributes pair NOT merged (Laravel's forceCreate skips setForeignAttributesForCreate's
// pending loop, :414-419; the Go write shells persist through a fresh session, so they drop
// pending the same way).
ForceCreate(dest any) error
// ForceCreateQuietly is ForceCreate with every model event suppressed —
// HasOneOrMany::forceCreateQuietly (:427).
ForceCreateQuietly(dest any) error
// ForceCreateMany is the slice form of ForceCreate — HasOneOrMany::forceCreateMany (:466).
ForceCreateMany(dests any) error
// ForceCreateManyQuietly is the slice form of ForceCreateQuietly —
// HasOneOrMany::forceCreateManyQuietly (:483).
ForceCreateManyQuietly(dests any) error
// GetExistenceCompareKey gets the key the existence query compares the parent key against —
// Eloquent's HasOneOrMany::getExistenceCompareKey (HasOneOrMany.php:571,
// `return $this->getQualifiedForeignKeyName();`).
GetExistenceCompareKey() string
// GetForeignKeyName gets the plain (unqualified) foreign key — HasOneOrMany::getForeignKeyName
// (HasOneOrMany.php:601, the last dot-segment of the stored qualified key). Oracle v12.55.1,
// executed: $user->posts() reports "user_id"; the morphMany sibling "commentable_id".
GetForeignKeyName() string
// GetQualifiedForeignKeyName gets the foreign key qualified with the related table —
// HasOneOrMany::getQualifiedForeignKeyName (HasOneOrMany.php:613, the column the declaration
// stored qualified — Concerns/HasRelationships.php:220/543/314/641). Oracle:
// "lax_posts.lax_user_id"; "lax_comments.commentable_id" for the morph form.
GetQualifiedForeignKeyName() string
// GetLocalKeyName gets the parent's local key — HasOneOrMany::getLocalKeyName
// (HasOneOrMany.php:623, `return $this->localKey;`). Oracle: "id".
GetLocalKeyName() string
// GetInverseRelationship gets the name of the inverse relationship the relation applies, or ""
// when none is in effect — Eloquent's SupportsInverseRelations::getInverseRelationship
// (vendor, illuminate/database v12.55.1, Relations/Concerns/SupportsInverseRelations.php:129,
// `return $this->inverseRelationship;`). The Go declaration is the relation descriptor's
// Inverse field, installed at wrap time as the state every read links its results and every
// write its created child back to the parent through; WithoutChaperone / WithoutInverse clear
// it. Oracle (v12.55.1, executed, /tmp/lalign-defaults-inverse/inverse_writeback_runtime.php):
// $user->posts()->getInverseRelationship() reports 'user' before the state is cleared, NULL
// after withoutChaperone / withoutInverse, and NULL on a relation declared without one.
GetInverseRelationship() string
// WithoutChaperone removes the chaperone / inverse write-back for this relation and returns
// the relation — Eloquent's SupportsInverseRelations::withoutChaperone (:151,
// `$this->inverseRelationship = null;`, chained by its `return $this;`). Oracle (same probe):
// a posts()->withoutChaperone()->get() result links nothing, and a
// withoutChaperone()->create()/make() child carries no inverse relation, where the plain
// create()/make() link the parent instance.
WithoutChaperone() HasOneOrManyRelation
// WithoutInverse is the alias of WithoutChaperone — SupportsInverseRelations::withoutInverse
// (:141, `return $this->withoutChaperone();`). Oracle (same probe): withoutInverse()->get()
// links nothing and getInverseRelationship() reports NULL afterwards.
WithoutInverse() HasOneOrManyRelation
}
HasOneOrManyRelation is the write surface shared by the HasOne / HasMany / MorphOne / MorphMany objects — Eloquent's HasOneOrMany methods on the relation. The methods whose names also exist on Query (Make / Save / Create / FirstOrNew / FirstOrCreate / UpdateOrCreate / CreateOrFirst / Upsert) take the Query signature — see RelationQuery's shadowing rule — and the attribute arguments accept the map-shaped values the relation write shells take.
type HasOneRelation ¶
type HasOneRelation interface {
HasOneOrManyRelation
// WithDefault overrides the relation's default related instance at call time — Eloquent's
// SupportsDefaultModels::withDefault (vendor v12.55.1, Relations/Concerns/SupportsDefaultModels
// .php:32, `$this->withDefault = $callback; return $this;`; HasOne.php:22 composes the trait).
// Accepted values match the declaration's WithDefault field — true / map[string]any /
// func(related, parent any) any; False, nil and an empty map yield no default (PHP falsy) —
// and the call replaces the one slot the declaration seeded. The default materialises exactly
// where the declaration's does: GetResults on a miss, or on a null parent key with no query at
// all (the fresh instance still carries the foreign key stamp — and the morph type, on the
// morph kinds); a real row always wins. Oracle (v12.55.1, executed,
// /tmp/lalign-defaults-inverse/runtime_withdefault.php):
// hasOne.missing-row.attributes {"foreign_key":2}, hasOne.null-key.queries 0,
// hasOne.declared-then-runtime.name "runtime".
WithDefault(value any) HasOneRelation
}
HasOneRelation is the HasOne object — HasOneOrManyRelation plus the call-time WithDefault slot Eloquent's HasOne composes through SupportsDefaultModels (HasOne.php:22). Declared rather than aliased because it adds a method: a plain HasMany object narrows through HasOneOrManyRelation, not through this name — the same rule the morph contracts below follow.
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
// WithDefault — the HasOneThrough form of HasOne.WithDefault. The default instance is a
// plain fresh instance of the related model with no attributes set
// (HasOneThrough::newRelatedInstanceFor); accepted values and the falsy-closure rule match
// HasOne.WithDefault.
WithDefault any
}
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 HasOneThroughRelation ¶
type HasOneThroughRelation interface {
RelationQuery
// FirstOrNew — see HasOneOrManyRelation.FirstOrNew. The signature mirrors Query.FirstOrNew.
FirstOrNew(dest any, attributes any, values ...any) error
// FirstOrCreate — see HasOneOrManyRelation.FirstOrCreate. The signature mirrors
// Query.FirstOrCreate.
FirstOrCreate(dest any, conds ...any) error
// UpdateOrCreate — see HasOneOrManyRelation.UpdateOrCreate. The signature mirrors
// Query.UpdateOrCreate.
UpdateOrCreate(dest any, attributes any, values any) error
// CreateOrFirst — see HasOneOrManyRelation.CreateOrFirst. The signature mirrors
// Query.CreateOrFirst.
CreateOrFirst(dest any, conds ...any) error
// WithDefault overrides the relation's default related instance at call time — HasOneThrough's
// SupportsDefaultModels::withDefault (HasOneThrough.php:22/24 composes the trait; :27-34
// getResults). The default instance is a plain newInstance of the related model
// (HasOneThrough::newRelatedInstanceFor, :108). The method rides the shared through base, so a
// HasManyThrough object carries it too — a Go surface superset: Laravel's HasManyThrough has no
// SupportsDefaultModels, and a many-result read never consults the slot (GetResults materialises
// a default for the single-result kinds only). Oracle (v12.55.1, executed,
// /tmp/lalign-defaults-inverse/runtime_withdefault.php): hasOneThrough.missing-row.class
// "RtCar" with attributes [], and hasOneThrough.null-key.queries 0.
WithDefault(value any) HasOneThroughRelation
}
HasOneThroughRelation is the write surface of the HasOneThrough object — the through create subset Eloquent's HasOneOrManyThrough carries. The through kinds hold no key on the related row, so the find-then-write methods carry no foreign key to set.
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). The bump is skipped while the parent's class
// ignores touches (Model::isIgnoringTouch) — the gate Eloquent's per-pivot touch rides through
// Relation::touch. 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 Many2ManyRelation ¶
type Many2ManyRelation = BelongsToManyRelation
Aliases (Go structural typing): each name denotes the same interface, so a returned object narrows through any of its kind's names.
type ModelToObserver ¶
type ModelWithConnection ¶
type ModelWithConnection interface {
// Connection gets the connection name for the model.
Connection() string
}
type ModelWithGlobalScopes ¶
type ModelWithGlobalScopes interface {
GlobalScopes() []GlobalScope
}
ModelWithGlobalScopes is implemented by a model that carries global scopes. The scopes apply in the declared order, which is Laravel's registration order — the order a boot() method added its scopes in. The order is observable when several scopes add wheres: a later scope's clauses follow the earlier ones', the way Laravel appends them.
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 ModelWithTimestamps ¶
type ModelWithTimestamps interface {
// UsesTimestamps reports whether the model stamps its automatic timestamps.
UsesTimestamps() bool
}
ModelWithTimestamps is implemented by a model that carries the per-instance timestamps flag — the Go form of Eloquent's HasTimestamps::$timestamps. Models embedding databaseorm.Timestamps answer through its promoted UsesTimestamps method, and the ORM reads the capability through this interface when it decides whether a write stamps. A model that declares its own timestamp fields without the embed reports nothing and keeps stamping.
type MorphMany ¶
type MorphMany struct {
Related any
Name string
TypeColumn string
IDColumn string
LocalKey string
OnQuery RelationCallback
// Inverse — see HasOne.Inverse.
Inverse string
}
MorphMany is the multi-result variant of MorphOne.
func (MorphMany) Kind ¶
func (MorphMany) Kind() RelationKind
type MorphManyRelation ¶
type MorphManyRelation interface {
HasManyRelation
// MorphType — see MorphOneRelation.MorphType.
MorphType() string
// QualifiedMorphType — see MorphOneRelation.QualifiedMorphType.
QualifiedMorphType() string
// MorphClass — see MorphOneRelation.MorphClass.
MorphClass() string
}
MorphManyRelation is the MorphMany object — HasManyRelation plus the morph-field accessors.
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
// Inverse — see HasOne.Inverse.
Inverse string
// WithDefault — the MorphOne form of HasOne.WithDefault. The default instance is a fresh
// related instance whose polymorphic id column is pre-set from the parent's local key and
// whose type column carries the relation's morph value (MorphOne::newRelatedInstanceFor);
// accepted values and the falsy-closure rule match HasOne.WithDefault.
WithDefault any
}
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 MorphOneRelation ¶
type MorphOneRelation interface {
HasOneRelation
// MorphType reports the morph type column without its table qualifier — Eloquent's
// MorphOneOrMany::getMorphType.
MorphType() string
// QualifiedMorphType reports the morph type column qualified with the related table —
// Eloquent's MorphOneOrMany::getQualifiedMorphType.
QualifiedMorphType() string
// MorphClass reports the parent's morph class value — the declared morph-map alias, or the
// parent's table name — Eloquent's MorphOneOrMany::getMorphClass.
MorphClass() string
}
MorphOneRelation is the MorphOne object — HasOneRelation (the call-time WithDefault slot included, MorphOne.php:22 composes SupportsDefaultModels) plus the morph-field accessors.
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
// MorphWith names extra relations to eager load for one polymorphic type — Laravel's
// MorphTo::morphWith([Class => ['relation', ...]]) (MorphTo.php:311-322), applied by
// getResultsByType to each resolved type's query. The map key is the type's morph-map alias —
// the string the type column carries, the 1:1 Go counterpart of Laravel's class-name key —
// and each value is a nested eager-load list in the With grammar ("user", "comments.author",
// "user:id,name"). The class's list merges into the relation's own nested loads the way
// getResultsByType's array_merge places it: being a plain relation list, its entries sit beside
// the relation-keyed nested loads and never overwrite one — a name the nested loads already
// carry is absorbed, the nested entry keeping its constraint and select list (oracle,
// illuminate/database v12.55.1, executed, /tmp/morphverify-probes/collision_dotted.php: the
// caller's `with(['commentable.author' => ...])` constraint survives the collision and the
// author read still carries `"name" = ?`, the author null). Applies to the eager and Load
// paths only, the paths Eloquent's getEager serves (oracle, illuminate/database v12.55.1,
// executed: /tmp/morphport-probes/morph_with.php — the Post type loads its author in a
// follow-up `select * from "mpw_authors" where "mpw_authors"."id" in (1)`, the unconfigured
// Video type receives no such query).
MorphWith map[string][]string
// MorphWithCount names relationship counts to load for one polymorphic type — Laravel's
// MorphTo::morphWithCount (MorphTo.php:337-346), applied per resolved type like MorphWith.
// Entries are the shapes Query.WithCount accepts (a "relation" or "relation as alias" string,
// or a RelationCount struct); the map key is the type's morph-map alias. Oracle (same probe):
// the Post type's rows carry `(select count(*) from "mpw_comments" where "mpw_posts"."id" =
// "mpw_comments"."post_id") as "comments_count"`, the unconfigured Video type no count column.
MorphWithCount map[string][]any
// Constrain holds one query constraint per polymorphic type — Laravel's
// MorphTo::constrain([Class => fn ($query) => ...]) (MorphTo.php:352-361), applied to the
// type's query after its eager loads and counts and before the owner-key in-list, the position
// getResultsByType gives it. The map key is the type's morph-map alias. Oracle (same probe):
// `where "title" != ? and "mpw_posts"."id" in (1, 2)` — the constraint's where leads the
// in-list, and the constrained row drops out of the loaded set.
Constrain map[string]RelationCallback
// WithTrashed / WithoutTrashed / OnlyTrashed carry the trashed-scope family Laravel's MorphTo
// buffers and replays per type (MorphTo::withTrashed / withoutTrashed / onlyTrashed,
// MorphTo.php:366/383/400 — each records a `when(true, callback)` macro and applies it
// immediately). Every flag is a no-op for a related type that declares no soft deletes — the
// state Laravel's macro-existence check leaves (`$query->hasMacro('withTrashed') ? $query->
// withTrashed() : $query`). Precedence when several flags are declared: OnlyTrashed >
// WithoutTrashed > WithTrashed. Oracle (illuminate/database v12.55.1, executed,
// /tmp/morphport-probes/trashed.php): Laravel's per-type read carries `"mpt_posts"."deleted_at"
// is null` by default, WithTrashed drops the predicate (include — `select * from "mpt_posts"
// where "mpt_posts"."id" in (2, 1)`), OnlyTrashed renders `"mpt_posts"."deleted_at" is not
// null`, WithoutTrashed keeps the default exclusion. The Go per-type eager read applies no
// related-model predicate when no flag is declared (the pre-existing divergence the
// soft-deletes corpus pins at laravel_port_soft_deletes_integration_test.go:1098): a declared
// WithTrashed therefore matches that Go default outcome, while WithoutTrashed forces Laravel's
// exclude-trashed default on the eager path; the object-path read, which carries the related
// model, honors all three flags directly.
WithTrashed bool
WithoutTrashed bool
OnlyTrashed bool
// WithDefault — the MorphTo form of HasOne.WithDefault. The default instance's class follows
// the type column: a value in the morph map (or a morph class name) yields that class, while
// an empty type column yields the parent's own class — MorphTo::newRelatedInstanceFor
// re-invokes $parent->relation(), and the null-type branch (morphEagerTo) carries the
// parent's own query as the related model. No attributes are set on the instance.
WithDefault any
}
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 MorphToManyRelation ¶
type MorphToManyRelation interface {
BelongsToManyRelation
// MorphType reports the pivot's morph type column name — Eloquent's MorphToMany::getMorphType.
MorphType() string
// QualifiedMorphType reports the pivot's morph type column qualified with the pivot table —
// Eloquent's MorphToMany::getQualifiedMorphTypeName.
QualifiedMorphType() string
// MorphClass reports the morph class value the pivot rows pin — the parent's morph class for
// MorphToMany, the related's for MorphedByMany — Eloquent's MorphToMany::getMorphClass.
MorphClass() string
// Inverse reports whether the relation was declared as the inverse side (morphedByMany) —
// Eloquent's MorphToMany::getInverse.
Inverse() bool
}
MorphToManyRelation is the MorphToMany / MorphedByMany object — BelongsToManyRelation plus the morph-field accessors.
type MorphToRelation ¶
type MorphToRelation interface {
BelongsToRelation
// MorphType reports the morph type column this table carries — Eloquent's MorphTo::getMorphType.
MorphType() string
// MorphOwnerKey reports the owner key column on each resolved related table — Eloquent's
// MorphTo owner key (read through BelongsTo::getOwnerKeyName); the default is "id".
MorphOwnerKey() string
}
MorphToRelation is the MorphTo object — BelongsToRelation plus the morph-field accessors.
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 MorphedByManyRelation ¶
type MorphedByManyRelation = BelongsToManyRelation
Aliases (Go structural typing): each name denotes the same interface, so a returned object narrows through any of its kind's names.
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 OfManyColumn ¶
OfManyColumn is one column/aggregate pair of an OfManyColumns configuration — the Go form of one entry in Laravel's ofMany(['published_at' => 'max', 'id' => 'max']): the column the aggregate is taken over and the aggregate itself ("MAX" or "MIN").
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 the relation builder object 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
// RelationQuery is a fresh chain — call any of Where / OrderBy / Get / First / Count / etc.
// on it — and carries the relation semantics: GetResults / Is / IsNot / RawUpdate and,
// through the per-kind interface (a Go narrowing assertion, e.g. rel.(HasManyRelation)), the
// write families (Make / Save / Create / Attach / Sync / ...). See RelationQuery.
//
// 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>)
//
// When the relation declares an Inverse (HasOne / HasMany / MorphOne / MorphMany), a model-row
// read through the returned Query — Get / First, a key-list Find / FindOrFail, a chunked page
// or a cursor page — stores the parent instance on each result model's inverse relation: the
// write-back Eloquent's chaperone after-query callback performs on every execution of the
// relation query. The callback sees the actual result set, so a widened query links every row
// it returns, not only rows whose foreign key matches the parent.
//
// Mirrors fedaco's model.NewRelation('foo'). RelationWriter (see Orm.Relation) remains only
// as the deprecated flat compatibility entry for the write path.
Related(parent any, relation string) RelationQuery
// 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.
//
// Deprecated: use Related(parent, relation) instead, Relation will be removed in a future
// major version. The relation builder object Related returns — RelationQuery and its per-kind
// write interfaces — carries the same write operations.
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 PivotFactory ¶
type PivotFactory func(parent any, attributes map[string]any, table string, exists bool) (PivotModel, error)
PivotFactory builds a pivot object for a many-to-many relation — the Go stand-in for Laravel's `using(SomePivot::class)` custom pivot class (BelongsToMany::using, vendor v12.55.1, BelongsToMany.php:350). The factory receives the arguments AsPivot's constructors take — the relation's parent, the pivot attribute map, the pivot table and the exists flag — and returns the object the relation's NewPivot / NewExistingPivot surfaces hand back.
The factory stands in for the custom class Laravel dispatches to through Model::newPivot (Model.php:1726, `$using::fromRawAttributes($parent, $attributes, $table, $exists)`), so it should build with fromRawAttributes semantics — the original bag left empty while !exists, so the attributes read dirty (oracle, executed, /tmp/decide-light-using/using_probe.php: `U2c custom newPivot dirty => ['level' => 'gold']`). The result must satisfy PivotModel; a result of this port's own Pivot / MorphPivot types is stamped by the relation itself (the fluent setPivotKeys / setRelatedModel pair a Go interface cannot re-dispatch), while any other custom type must return fully stamped: pivot keys in place and the related model set. nil keeps the default constructors.
type PivotKeyed ¶
type PivotKeyed interface {
PivotKeys() []string
}
PivotKeyed is implemented by a pivot struct that names the pivot-table columns identifying one pivot row — AsPivot's (foreignKey, relatedKey) pair, plus the morph type on a MorphPivot, the order setKeysForSelectQuery writes them. Fresh/Refresh match on these columns because a pivot row carries no primary key of its own; the values come from the struct's current fields.
type PivotModel ¶
type PivotModel interface {
PivotKeyed
// Attributes gets the pivot's attribute bag (Model::getAttributes' by-value semantics).
Attributes() map[string]any
// GetTable gets the pivot table the row lives on.
GetTable() string
// Exists reports the persisted flag the constructors set and save / delete maintain.
Exists() bool
}
PivotModel is the minimal pivot-object surface the many-to-many relation's pivot-construction methods hand back and the port's pivot call sites act on — the Go stand-in for the common supertype every Laravel pivot class shares by inheriting Illuminate\Database\Eloquent\Relations \Pivot. A value of this interface can be handed to Fresh/Refresh (PivotKeyed names the identifying columns a keyless pivot row is re-read by), and its attribute bag, table and exists flag are the state a hydrated $model->pivot exposes. A caller needing more — the fluent setters, the save / delete family, the morph getters — narrows to the concrete type (this port's relations.Pivot / relations.MorphPivot), the way PHP code narrows on the class.
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 the relation builder object 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. See RelationQuery for the object surface.
Related(parent any, name string) RelationQuery
// 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.
//
// Deprecated: use Related(parent, name) instead, Relation will be removed in a future major
// version. The relation builder object Related returns — RelationQuery and its per-kind write
// interfaces — carries the same write operations.
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)
// GetCountForPagination gets the count a paginator draws its page from, mirroring Laravel's
// Builder::getCountForPagination (Builder::runPaginationCountQuery): the count is built on a
// clone, so the query keeps its own clauses and bindings, and a grouped or having query is
// counted by wrapping its select in a derived table named "aggregate_table" — the count counts
// groups, not rows, unlike Count(), which keeps Laravel's count() semantics of one aggregate
// over the grouped result. Paginate feeds its total from this method.
GetCountForPagination(columns ...string) (int64, error)
// Create inserts new record into the database.
Create(value any) error
// Chunk reads the query in pages of size rows, scanning every page into dest — a non-nil
// pointer to a slice of models — and calling callback with the 1-based page number after the
// page was scanned, mirroring Eloquent's BuildsQueries::chunk: a query without an order is
// ordered by the model's qualified key ascending first, the caller's offset and limit are
// honoured, and a callback returning errors.DatabaseChunkStopped stops the walk cleanly — the
// Go form of Laravel's `return false`.
Chunk(size uint64, dest any, callback func(page int) error) error
// ChunkById chunks by comparing ids, mirroring BuildsQueries::chunkById: each page is fetched
// with ForPageAfterId using the last row's id as the keyset, so the walk pays no growing
// offset. On a relation read the key column defaults to the related model's qualified key and
// the alias to its bare key name, the way BelongsToMany / HasOneOrManyThrough::chunkById
// override the builder defaults for a joined read; elsewhere the column is the model's bare
// key name (Eloquent's Builder::defaultKeyName). column may be (column) or (column, alias).
ChunkById(size uint64, dest any, callback func(page int) error, column ...string) error
// ChunkByIdDesc is ChunkById in descending order, mirroring BuildsQueries::chunkByIdDesc.
ChunkByIdDesc(size uint64, dest any, callback func(page int) error, column ...string) 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
// Each executes the callback over every matching model one at a time, reading 1000 rows per
// statement like BuildsQueries::each: dest — a non-nil pointer to a model — holds the current
// row, index is the model's key within its page, and a callback returning
// errors.DatabaseChunkStopped stops the walk cleanly (Laravel's `return false`).
Each(dest any, callback func(index int) error) error
// EachById executes the callback over every matching model one at a time, walking the keyset
// like BuildsQueries::eachById. dest holds the current row and index is the model's 0-based
// ordinal across the whole iteration — Laravel's ((page-1)*size + key) arithmetic.
EachById(size uint64, dest any, callback func(index int) error, column ...string) error
// 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
// CreateOrFirst attempts to create a record with the attributes (and values) without reading
// first, mirroring Eloquent's Builder::createOrFirst: when the insert trips a unique
// constraint the row matching the attributes is read back — on the write connection — and
// returned instead of the error. The insert runs inside a savepoint when the query is bound
// to a transaction.
CreateOrFirst(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 and with the query's pending attributes
// (WithAttributes), which merge underneath them.
FirstOrNew(dest any, attributes any, values ...any) error
// Fresh reads model's row back from the database into dest — a new instance — mirroring
// Eloquent's Model::fresh: the read matches on the model's primary key (a pivot struct without
// one declares its keys through PivotKeys instead), global scopes are skipped, the read runs on
// the write connection, with names relations to eager-load on the fresh instance, and a model
// with no key — or one the database no longer holds — leaves dest zero-valued, Laravel's null.
// A model that declares neither a primary key nor PivotKeys is refused with a named error.
Fresh(model any, dest any, with ...string) error
// Refresh re-reads model's row into model itself, mirroring Eloquent's Model::refresh (which
// takes no $with): the same key match and scope-skipping read as Fresh, applied in place
// through firstOrFail — a missing row reports errors.OrmModelNotFoundNoIds, firstOrFail's
// id-less message — and every relation the model already carries loaded is re-loaded, the Go
// form of refresh()'s reload of its
// non-pivot relations. A model with no key reads nothing and is returned unchanged.
Refresh(model 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
// Lazy walks the query in pages of chunkSize (default 1000) and hands each hydrated model to
// callback through dest — a non-nil pointer to a model — with index counting the models seen
// so far, mirroring BuildsQueries::lazy: a query without an order is ordered by the model's
// qualified key ascending, a chunk size below 1 is refused (errors.QueryInvalidChunkSize), and
// errors.DatabaseChunkStopped stops the walk cleanly. Go has no lazy collection, so the walk
// runs immediately and reports its error; the page sequence is the one Laravel's LazyCollection
// would pull.
Lazy(dest any, callback func(index int) error, chunkSize ...uint64) error
// LazyById is Lazy with chunkById's keyset, mirroring BuildsQueries::lazyById: each page is
// fetched with forPageAfterId using the last model's id as the keyset, with the same
// column/alias defaults as ChunkById.
LazyById(chunkSize uint64, dest any, callback func(index int) error, column ...string) error
// LazyByIdDesc is LazyById in descending order, mirroring BuildsQueries::lazyByIdDesc.
LazyByIdDesc(chunkSize uint64, dest any, callback func(index int) error, column ...string) error
// Limit the number of records returned.
Limit(limit int) Query
// Take is an alias of Limit, mirroring Eloquent's Builder::take. On the has-family and
// through relation objects both Take and Limit are Eloquent's relation-level limit
// (HasOneOrMany::limit HasOneOrMany.php:555, HasOneOrManyThrough::limit
// HasOneOrManyThrough.php:772): the plain limit for an existing parent, the per-parent group
// limit — the row_number() over (partition by <key>) derived table — for a parent that does
// not exist, returning the relation object (oracle
// /tmp/followup-take-grouplimit/take_grouplimit.php H1 / H7 / T1 / T5). The many-to-many
// object still promotes the builder's plain limit (BelongsToMany::take, BelongsToMany.php:1492,
// is not yet ported).
Take(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
// Make builds an unsaved model instance carrying the query's pending attributes (recorded by
// WithAttributes) and the attributes it is given, mirroring Laravel's Builder::make: the
// pending attributes merge underneath, so an attribute passed here wins; nothing is written.
Make(dest any, attributes ...any) error
// Model sets the model instance to be queried.
Model(value any) Query
// OfMany configures a HasOne, MorphOne or HasOneThrough relation to return one row per parent
// through the aggregate join Laravel's ofMany installs, mirroring its string form: the
// column's aggregate is taken per parent and the related model's key joins the aggregate set
// with the same aggregate, so ties resolve to the extreme key. Column and aggregate default to
// "id" / "MAX". Intended for use inside a relation's OnQuery or 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
// OfManyColumns configures the relation the way ofMany's ordered column map does, e.g.
// ofMany(['published_at' => 'max', 'id' => 'max']): the pairs are taken in order with each
// later pair breaking ties in the earlier ones, and the related model's key is appended with
// MAX when the columns omit it.
OfManyColumns(columns ...OfManyColumn) Query
// LatestOfMany is shorthand for ofMany with every column aggregated "MAX" — Laravel's
// latestOfMany($column), which defaults to "id". The related model's key is appended as MAX
// when the columns omit it. Mirrors fedaco's latestOfMany().
LatestOfMany(column ...string) Query
// OldestOfMany is shorthand for ofMany with every column aggregated "MIN" — Laravel's
// oldestOfMany($column), which defaults to "id". The related model's key is appended as MAX
// when the columns omit it, exactly as ofMany appends it. 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, or the given direction. The direction must be asc
// or desc, as Laravel requires; a custom direction such as "DESC NULLS LAST" goes through OrderByRaw.
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
// OrWhereColumn adds an "or where column" comparison clause to the query, mirroring
// Builder::orWhereColumn. One trailing column means equality with that column; two mean the
// operator and then the column.
OrWhereColumn(column1 string, column2 ...string) 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
// OrWhereNot adds a negated "or where" clause, mirroring Eloquent's Builder::orWhereNot
// (Builder.php:420). A callback with no other arguments runs as one nested group
// carrying the "or not" connector; a column with its value is handed to the underlying
// query builder, which renders "or not col = ?"; an array first argument expands through
// the inner builder's addArrayOfWheres under the "or not" boolean —
// `or not (not "b" = ? or not "c" = ?)`.
OrWhereNot(query any, 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
// SimplePaginate retrieves one page of rows without counting the total, mirroring Laravel's
// Builder::simplePaginate (Eloquent Builder.php:1143): page and limit follow the same
// conventions as Paginate — a non-positive page falls back to 1 and a non-positive limit to
// 15 — the query runs with one probe row (limit+1), dest — a pointer to a slice — receives at
// most limit rows with the probe row trimmed away, and the returned bool reports whether the
// probe row was present, which is Laravel's hasMorePages(). No count query runs, so the page
// carries no total; relation queries inherit the method through their embedded Query surface.
SimplePaginate(page, limit int, dest any) (bool, error)
// Pluck retrieves a single column from the database, mirroring Laravel's pluck($column, $key):
// dest is a pointer to a slice that receives the values, or — when a key column is given — a
// pointer to a map keyed by that column's values.
Pluck(column string, dest any, key ...string) 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 immediately — Eloquent's Builder::scopes(), not the
// deferred global-scope registration — so clauses chained after the call follow the scope's.
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)
// UsesTimestamps reports whether writes through the query stamp the model's automatic timestamps,
// the query-level form of Eloquent's HasTimestamps::usesTimestamps: false while a
// WithoutTimestamps scope is active, and false when the query's model carries the per-instance
// flag (a databaseorm.Timestamps whose Disabled field names it ignored, read through the model's
// own UsesTimestamps method). A query with no model attached reports the scope alone.
UsesTimestamps() bool
// Value retrieves a single column of the first row into dest, mirroring Laravel's
// Builder::value.
Value(column string, dest any) error
// ValueOrFail retrieves a single column of the first row into dest, mirroring Laravel's
// Builder::valueOrFail: a read that matches no row reports the model-not-found error naming
// the model instead of leaving dest untouched.
ValueOrFail(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 adds a "where" clause to the query, mirroring Eloquent's Builder::where. A callback
// with no other arguments runs against a new query without relationships: its eager loads
// merge into this query and its wheres join this query as one nested group. Every other
// condition is applied to the underlying query builder as it is written; raw SQL goes through
// WhereRaw, the way Eloquent separates where() from whereRaw().
Where(query any, args ...any) Query
// WhereRaw adds a raw where clause, mirroring Eloquent's Builder::whereRaw: the fragment renders
// verbatim and the values bind to its placeholders in order.
WhereRaw(query string, args ...any) Query
// OrWhereRaw adds a raw where clause with the "or" connector, mirroring Builder::orWhereRaw.
OrWhereRaw(query string, 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
// WhereColumn adds a "where" clause comparing two columns to the query, mirroring
// Builder::whereColumn. One trailing column means equality with that column; two mean the
// operator and then the column.
WhereColumn(column1 string, column2 ...string) 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
// WhereNot adds a negated where clause, mirroring Eloquent's Builder::whereNot
// (Builder.php:407), which is where($column, $operator, $value, $boolean.' not'). A callback
// with no other arguments runs as one nested group carrying the "and not" connector; a
// column with its value (or with no value) is handed to the underlying query builder, which
// renders "and not col = ?" — the negation rides the connector; an array first argument
// expands through the inner builder's addArrayOfWheres under the "and not" boolean,
// negating every column inside one group — `and not (not "b" = ? and not "c" = ?)` —
// where the raw Query\Builder::whereNot nests twice (`and not (("b" = ? and "c" = ?))`).
WhereNot(query any, 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
// WithoutTimestamps runs the callback with the query's automatic created_at / updated_at
// stamping suspended, mirroring Eloquent's HasTimestamps::withoutTimestamps for the query-level
// Go surface: while a scope is active, writes through the query write neither column — a value
// the caller supplied is still written — nested scopes stay suspended with each restoring
// exactly its own, and the suspension is lifted before the callback's error (or panic)
// propagates. The callback's error is returned unchanged.
WithoutTimestamps(callback func() error) error
// 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 QueryWithInverseChaperone ¶
type QueryWithInverseChaperone interface {
// InverseRelationship reports the inverse relation name the write-back links results to, ""
// when none is in effect (never installed, or cleared).
InverseRelationship() string
// WithoutInverseChaperone clears the write-back state — the object's WithoutChaperone /
// WithoutInverse call.
WithoutInverseChaperone()
}
QueryWithInverseChaperone is the optional capability a Query implements when it carries the inverse (chaperone) write-back state a relation read installs — the Go form of the state SupportsInverseRelations::$inverseRelationship keeps on the relation. The relation objects' WithoutChaperone reaches it through a type assertion (the relations package cannot name database/gorm types); a Query implementation without the capability — a mock, a foreign driver — is left as it stands. database/gorm implements it on OrmBuilder.
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. Pass []any{"*"} to
// resolve the distinct morph values from the parent table's type column at compile time,
// mirroring Eloquent's hasMorph(['*']) auto-discovery; Has()/WhereHas() on a MorphTo
// relation takes that path automatically, the way Eloquent's has() delegates to hasMorph.
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. column accepts a column name, a
// table-qualified name, "*", or a raw expression (database/query's Raw/Expression), the
// string|Expression union Laravel's withAggregate accepts; relation may carry an "as" rename
// ("Books as book_total").
WithAggregate(relation string, column any, fn string, args ...any) Query
// WithCount adds sub-select queries to count the relations. Each entry may be either a
// string ("Books", or "Books as book_total" for a rename) 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 string, column any, args ...any) Query
// WithMin adds sub-select queries to include the min of the relation's column.
WithMin(relation string, column any, args ...any) Query
// WithSum adds sub-select queries to include the sum of the relation's column.
WithSum(relation string, column any, args ...any) Query
// WithAvg adds sub-select queries to include the average of the relation's column.
WithAvg(relation string, column any, 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
// WhereAttachedTo constrains the query to the rows attached to the given model through a
// many-to-many relation, mirroring Laravel's whereAttachedTo: the relation defaults to the
// plural camel form of the related model's type name, and the related model's key list matches
// inside the relation's existence subquery the way whereKey writes it (integer keys inlined
// through whereIntegerInRaw, other keys bound).
WhereAttachedTo(related any, relation ...string) Query
// OrWhereAttachedTo is WhereAttachedTo with an "or" conjunction. Mirrors Laravel's
// orWhereAttachedTo.
OrWhereAttachedTo(related any, relation ...string) Query
// WhereAttachedToCollection is WhereAttachedTo for a collection of models, mirroring Laravel's
// whereAttachedTo called with a collection: every model's key joins the list the existence
// subquery matches against the related table's key.
WhereAttachedToCollection(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 RelationQuery ¶
type RelationQuery interface {
Query
// GetResults runs the relation read Eloquent's Relation::getResults runs: for the
// single-result kinds (HasOne / MorphOne / BelongsTo / MorphTo / HasOneThrough) it reads one
// row into dest — the WithDefault instance materialises on a miss when the relation declares
// one or sets one at call time through WithDefault — and for the many-result kinds it reads
// every matching row.
GetResults(dest any) error
// Is reports whether model is this relation's related model for the parent it was resolved
// from, mirroring Eloquent's ComparesRelatedModels::is: the related tables must match and the
// per-kind keys — the parent key and the model's related key — must be equal.
Is(model any) bool
// IsNot is the negation of Is, mirroring ComparesRelatedModels::isNot.
IsNot(model any) bool
// RawUpdate updates the related rows through the relation query without global scopes,
// mirroring Relation::rawUpdate. attrs maps column names to values and the result reports the
// affected rows.
RawUpdate(attrs map[string]any) (*db.Result, error)
// Touch stamps the related model's updated-at column (or the named column) to now on every row
// the relation resolves to, mirroring Relation::touch: the constrained update with global
// scopes dropped, no model events. BelongsTo / MorphTo with an absent parent key and a related
// model that ignores touches are no-ops reporting zero affected rows. It shadows Query.Touch by
// design — same signature, relation semantics.
Touch(column ...string) (*db.Result, error)
// GetParent gets the parent model instance the relation was resolved from.
GetParent() any
// GetRelated gets the related model instance the relation targets. A MorphTo relation
// resolves its related model per parent row, so it reports nil.
GetRelated() any
// GetQualifiedParentKeyName gets the key the relation's parent side hangs off, qualified with
// the table that owns it, mirroring Relation::getQualifiedParentKeyName and its per-kind
// overrides: the has-family and the many-to-many qualify the parent's local (parent) key on
// the parent table, BelongsTo / MorphTo the parent's own primary key on its table, and the
// through kinds the through parent's second local key on the through table.
GetQualifiedParentKeyName() string
// CreatedAt gets the name of the parent model's "created at" column — Eloquent's
// Relation::createdAt (vendor, illuminate/database v12.55.1, Relations/Relation.php:373,
// `return $this->parent->getCreatedAtColumn();` — the parent model's column, not the
// related's; oracle v12.55.1, executed, /tmp/lalign-probes/accessors.php: $user->posts()
// reports the user class's "user_created_at" while the posts class declares "post_created_at").
// The Go form resolves the column from the parent model's schema — the field the write path
// stamps on insert (database/gorm's modelCreatedAtColumn) — and reports Laravel's
// static::CREATED_AT default "created_at" when the parent declares none. BelongsToMany
// overrides the pair to prefer the pivot's withTimestamps columns (BelongsToMany.php:1559/1569,
// `$this->pivotCreatedAt ?? $this->parent->getCreatedAtColumn() ?? Model::CREATED_AT`): the
// many-to-many object reports the pivot column its timestamp declaration resolved — the Pivot
// struct's tagged / conventional fields or PivotTimestamps: true — and the parent's column when
// none is declared, each column on its own (oracle v12.55.1, executed,
// /tmp/btm-pivot-ts-probe.php: withTimestamps('pivot_created_at', 'pivot_updated_at') reports
// the pivot names, no withTimestamps reports the parent's "user_created_at" /
// "user_updated_at", and withTimestamps('pivot_created_at') mixes them).
CreatedAt() string
// UpdatedAt is CreatedAt's updated-at sibling — Relation::updatedAt (Relations/Relation.php:383,
// `$this->parent->getUpdatedAtColumn();`; oracle: "user_updated_at" from the parent class's
// UPDATED_AT), with Laravel's static::UPDATED_AT default "updated_at" when the parent declares
// none, and the same BelongsToMany pivot-column preference (BelongsToMany.php:1569).
UpdatedAt() string
}
RelationQuery is the base surface of the relation builder object Orm.Related / Query.Related return — the Go form of Eloquent's Relation classes as first-class query builders. The object embeds Query, so every builder method (Where / OrderBy / Get / First / Count / the chunk family / ...) chains on it already scoped to the relation's related rows, and the base adds the relation semantics Eloquent's Relation carries: the read result shape, the parent/related comparisons, the raw update and the parent/related accessors.
The per-kind write families live on the kind-specific interfaces below, reached through a Go narrowing assertion:
rel := q.Related(&user, "Books") // RelationQuery books := rel.(orm.HasManyRelation) // + HasOneOrManyRelation's write family require.NoError(t, books.Save(&book))
Documented Go divergences (vs PHP):
- Promoted builder methods return the builder, not the relation object, so relation-only methods (One, the wherePivot family) are called before the first builder chain.
- Methods that share their name with a Query method (Make / Save / SaveQuietly / Create / FirstOrNew / FirstOrCreate / UpdateOrCreate / CreateOrFirst / Upsert) keep the Query signature — a Go type cannot carry two same-named methods — and the object applies relation semantics (foreign key / pivot scoping) underneath it. RelationWriter (Orm.Relation) keeps the legacy map-first signatures for callers that prefer them.
type RelationWriter
deprecated
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.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
Save(child any) error
// SaveMany is the slice form of Save. children must be a slice or pointer-to-slice.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
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).
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
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.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
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.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
Create(dest any) error
// CreateMany is the slice form of Create.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
CreateMany(dests any) error
// Make returns an unsaved new instance of the related model carrying attrs with the foreign
// key (and morph type, for MorphOne/MorphMany) pre-set from parent — Laravel's
// HasOneOrMany::make. Nothing is persisted. Supported kinds: HasOne, HasMany, MorphOne,
// MorphMany.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
Make(attrs map[string]any, dest any) error
// MakeMany is the slice form of Make: one unsaved instance per record, in record order. dests
// must be a pointer to a slice of structs (or pointers to structs). Supported kinds as Make.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
MakeMany(records []map[string]any, 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. For the
// BelongsToMany kinds the lookup is the pivot-joined relation read, a hit carries the hydrated
// Pivot struct, and a miss leaves dest as it was — no foreign key to pre-set.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
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. For the BelongsToMany
// kinds the search is the plain related read and the miss response is the attrs+values overlay.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
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. The lookup is Laravel's two-level search — the pivot-joined
// relation read, then the plain related read whose hit is attached — before createOrFirst.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
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 the BelongsToMany kinds it is BelongsToMany::updateOrCreate
// — firstOrCreate's three-level search, which attaches a found-but-unattached row and
// creates+attaches on a miss, then fill+save on every row that was not freshly created.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
UpdateOrCreate(attrs, values map[string]any, dest any) error
// CreateOrFirst attempts the insert with attrs+values immediately — no lookup first — and,
// when the insert trips a unique constraint, reads back the row matching attrs and returns it,
// mirroring Laravel's createOrFirst with its UniqueConstraintViolationException catch: the
// HasOneOrMany kinds re-read over the write connection (useWritePdo), the through kinds on the
// default connection. For the BelongsToMany kinds the insert is the related row plus the pivot
// attach (BelongsToMany::create), the catch reads the related row back and attaches it, and a
// missed read-back, a pivot violation, or an already-attached pivot row re-reads through the
// relation on the write connection. Supported kinds: HasOne, HasMany, MorphOne, MorphMany,
// HasOneThrough, HasManyThrough, Many2Many, MorphToMany.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
CreateOrFirst(attrs, values map[string]any, dest any) error
// Upsert merges the parent key (and the morph type, for MorphOne/MorphMany) into every row and
// delegates to the query-level upsert, mirroring HasOneOrMany::upsert / MorphOneOrMany::upsert.
// Supported kinds: HasOne, HasMany, MorphOne, MorphMany.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
Upsert(values []map[string]any, uniqueBy []string, update ...any) (*db.Result, error)
// Associate sets parent's foreign key (and morph_type for MorphTo) to point at owner, then
// persists parent. Supported kinds: BelongsTo, MorphTo. A nil owner — Laravel's
// associate(null) — clears the foreign key (and morph type) and persists instead; a non-nil
// owner must be a pointer to a struct.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
Associate(owner any) error
// Dissociate clears parent's foreign key (and morph_type for MorphTo) and persists parent.
// Supported kinds: BelongsTo, MorphTo.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
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.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
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.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
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.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
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.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
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).
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
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.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
SyncWithPivotValues(ids []any, pivotValues map[string]any) (*db.SyncResult, error)
// SyncWithoutDetaching is Sync minus the detach step — adds missing entries only.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
SyncWithoutDetaching(ids []any) (*db.SyncResult, error)
// SyncWithoutDetachingWithPivot is SyncWithPivot minus the detach step.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
SyncWithoutDetachingWithPivot(idsWithAttrs map[any]map[string]any) (*db.SyncResult, error)
// Toggle attaches missing entries and detaches existing ones.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
Toggle(ids []any) (*db.SyncResult, error)
// ToggleWithPivot is Toggle with per-ID pivot column values for newly attached rows.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
ToggleWithPivot(idsWithAttrs map[any]map[string]any) (*db.SyncResult, error)
// UpdateExistingPivot updates pivot columns for an already-attached id.
//
// Deprecated: legacy flat RelationWriter path — use the relation builder object instead (Related / RelationQuery).
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 the relation builder object: a full Query chain (Where/OrderBy/Get/...) already scoped by the relation's foreign key, which additionally carries the relation semantics (RelationQuery).
Deprecated: RelationWriter is the legacy flat write path. Use the relation builder object instead — Query.Related / Orm.Related return a RelationQuery whose per-kind write interfaces (e.g. HasOneOrManyRelation, BelongsToRelation, BelongsToManyRelation, the through interfaces) carry these write families on the object itself, mirroring Laravel's Relation classes. RelationWriter is kept for compatibility; it will be removed in a future major version.
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
}