Documentation
¶
Overview ¶
Package activerecord is a pure-Go (CGO-free) reimplementation of Rails' ActiveRecord ORM: the interpreter-independent layers that turn a model + relation description into SQL, run it, and materialize records, exactly as MRI's activerecord gem does. Talking to the database is a host seam — an Adapter the host injects (wired to go-ruby-sqlite3 / go-ruby-pg) — so this package is 100% Ruby-free and produces byte-faithful SQL that a differential oracle compares to ActiveRecord's own output across adapters.
Scope ¶
- Relation: lazy, chainable query building (where/not/or/order/limit/offset/ group/having/joins/left_joins/select/distinct + find/find_by/first/last/ take, aggregates, pluck, exists?) rendered to a per-Dialect SQL string via Relation.ToSQL, byte-faithful to ActiveRecord, plus the executable counterparts (Relation.ToArray/Relation.Pluck/Relation.Exists/…).
- Schema & migrations: create_table / add_column / add_index / add_foreign_key / drop_table / remove_column / rename_column DDL and a Migrator that runs migrations through the adapter with a schema_migrations ledger.
- Associations & eager loading: belongs_to / has_many / has_one / has_and_belongs_to_many (and :through) join SQL, plus [Includes]/Preload multi-query materialization.
- Validations: presence / length / format / numericality / inclusion / exclusion / uniqueness — producing an Errors shaped like ActiveModel::Errors with ActiveRecord's default messages.
- Attributes & persistence: readers/writers, dirty tracking (changed?/ changes), type casting, and Save/Model.Create/Destroy through the adapter with timestamps and generated-key assignment.
- Lifecycle: the full before/after callback chain, [Transaction]s with nested savepoints, a prepared-statement StatementCache, and single-table inheritance (Model.STI/Model.Subclass).
Only the database round-trip itself — Adapter.Execute/Adapter.ExecuteDML and connection pooling — is the host's; everything ActiveRecord does around it lives here.
Ruby value model ¶
Attribute and bind values are represented by an [any] drawn from a small, fixed set of Go types so a host (go-embedded-ruby) can map its object graph to and from this package:
Ruby Go ---- -- nil nil true / false bool Integer int, int64, *big.Int Float float64, float32 String string Symbol Symbol Array []any Time time.Time
Index ¶
- Variables
- func AddColumnSQL(dialect Dialect, table, name, typ string, opts ...ColOpt) string
- func AddForeignKeySQL(dialect Dialect, fromTable, toTable, column, primaryKey, name string) string
- func AddIndexSQL(dialect Dialect, table string, cols []string, unique bool, name string) string
- func AddTimestampsSQL(dialect Dialect, table string) []string
- func ChangeColumnNullSQL(dialect Dialect, table, column, typ string, null bool) string
- func Count(a Adapter, r *Relation) (int64, error)
- func Delete(a Adapter, rec *Record) error
- func Destroy(a Adapter, rec *Record) (bool, error)
- func DropTableSQL(dialect Dialect, table string) string
- func Exists(a Adapter, r *Relation) (bool, error)
- func Pluralize(word string) string
- func Preload(a Adapter, parents []*Record, name string) error
- func RemoveColumnSQL(dialect Dialect, table, column string) string
- func RemoveIndexSQL(dialect Dialect, table string, cols []string, name string) string
- func RenameColumnSQL(dialect Dialect, table, from, to string) string
- func Save(a Adapter, rec *Record, opts ...SaveOption) (bool, error)
- func SchemaMigrationsTableSQL(dialect Dialect) string
- func Tableize(className string) string
- func Transaction(a Adapter, fn func() error) (err error)
- func TransactionDepth(a Adapter) int
- type Adapter
- type AssocKind
- type AssocOpt
- type Association
- type Callback
- type Change
- type ColOpt
- type Column
- type Dialect
- type Errors
- type LengthOpts
- type Migrator
- func (mg *Migrator) AppliedVersions() ([]string, error)
- func (mg *Migrator) Dialect() Dialect
- func (mg *Migrator) EnsureSchemaMigrations() error
- func (mg *Migrator) Execute(sql string) error
- func (mg *Migrator) Migrate(version string, up func(*Migrator) error) (bool, error)
- func (mg *Migrator) Rollback(version string, down func(*Migrator) error) (bool, error)
- type Model
- func (m *Model) AddColumn(name, typ string) *Model
- func (m *Model) AfterCommit(fn Callback) *Model
- func (m *Model) AfterCreate(fn Callback) *Model
- func (m *Model) AfterDestroy(fn Callback) *Model
- func (m *Model) AfterRollback(fn Callback) *Model
- func (m *Model) AfterSave(fn Callback) *Model
- func (m *Model) AfterUpdate(fn Callback) *Model
- func (m *Model) AfterValidation(fn Callback) *Model
- func (m *Model) All() *Relation
- func (m *Model) Association(name string) *Association
- func (m *Model) BeforeCreate(fn Callback) *Model
- func (m *Model) BeforeDestroy(fn Callback) *Model
- func (m *Model) BeforeSave(fn Callback) *Model
- func (m *Model) BeforeUpdate(fn Callback) *Model
- func (m *Model) BeforeValidation(fn Callback) *Model
- func (m *Model) BelongsTo(name, className string, opts ...AssocOpt) *Model
- func (m *Model) Build(attrs map[string]any) *Record
- func (m *Model) Columns() []Column
- func (m *Model) Create(a Adapter, attrs map[string]any, opts ...SaveOption) (*Record, error)
- func (m *Model) DefaultScope(body func(*Relation) *Relation) *Model
- func (m *Model) FindByRecord(a Adapter, cond map[string]any) (*Record, error)
- func (m *Model) FindByStatement(attrs ...string) *PreparedStatement
- func (m *Model) FindRecord(a Adapter, id any) (*Record, error)
- func (m *Model) FindStatement() *PreparedStatement
- func (m *Model) HABTM(name, className string, opts ...AssocOpt) *Model
- func (m *Model) HasColumn(name string) bool
- func (m *Model) HasMany(name, className string, opts ...AssocOpt) *Model
- func (m *Model) HasOne(name, className string, opts ...AssocOpt) *Model
- func (m *Model) InsertSQL(attrs map[string]any) string
- func (m *Model) Joins(names ...any) *Relation
- func (m *Model) Load(attrs map[string]any) *Record
- func (m *Model) LoadSTI(row Row) *Record
- func (m *Model) Order(cols ...any) *Relation
- func (m *Model) Register(others ...*Model) *Model
- func (m *Model) STI(column string) *Model
- func (m *Model) Scope(name string, body func(*Relation) *Relation) *Model
- func (m *Model) ScopeNames() []string
- func (m *Model) Select(cols ...any) *Relation
- func (base *Model) Subclass(className string) *Model
- func (m *Model) Unscoped() *Relation
- func (m *Model) Validate(rec *Record) *Errors
- func (m *Model) ValidatesExclusion(attr string, in []any) *Model
- func (m *Model) ValidatesFormat(attr string, with *regexp.Regexp) *Model
- func (m *Model) ValidatesInclusion(attr string, in []any) *Model
- func (m *Model) ValidatesLength(attr string, o LengthOpts) *Model
- func (m *Model) ValidatesNumericality(attr string, o NumericalityOpts) *Model
- func (m *Model) ValidatesPresence(attr string) *Model
- func (m *Model) ValidatesUniqueness(attr string, exists func(rec *Record) bool) *Model
- func (m *Model) Where(cond ...any) *Relation
- type NumericalityOpts
- type PreparedAdapter
- type PreparedStatement
- type Range
- type Record
- func (r *Record) AttributeChanged(name string) bool
- func (r *Record) Attributes() map[string]any
- func (r *Record) Changed() bool
- func (r *Record) ChangedAttributeNames() []string
- func (r *Record) Changes() map[string]Change
- func (r *Record) Errors() *Errors
- func (r *Record) Get(name string) (any, bool)
- func (r *Record) IsDestroyed() bool
- func (r *Record) IsNewRecord() bool
- func (r *Record) IsPersisted() bool
- func (r *Record) PreloadedAssociation(name string) []*Record
- func (r *Record) SaveClean()
- func (r *Record) Set(name string, v any) *Record
- func (r *Record) Update(a Adapter, attrs map[string]any, opts ...SaveOption) (bool, error)
- func (r *Record) Valid() bool
- func (r *Record) Validate() *Errors
- type Relation
- func (r *Relation) AverageSQL(col string) string
- func (r *Relation) Count(a Adapter) (int64, error)
- func (r *Relation) CountColumnSQL(col string) string
- func (r *Relation) CountSQL() string
- func (r *Relation) DeleteAllSQL() string
- func (r *Relation) Distinct(on ...bool) *Relation
- func (r *Relation) Exists(a Adapter) (bool, error)
- func (r *Relation) ExistsSQL() string
- func (r *Relation) Find(id any) *Relation
- func (r *Relation) FindBy(cond map[string]any) *Relation
- func (r *Relation) FindEach(a Adapter, batchSize int, fn func(*Record) error) error
- func (r *Relation) First() *Relation
- func (r *Relation) FirstRecord(a Adapter) (*Record, error)
- func (r *Relation) From(table string) *Relation
- func (r *Relation) Group(cols ...any) *Relation
- func (r *Relation) Having(cond ...any) *Relation
- func (r *Relation) Ids(a Adapter) ([]any, error)
- func (r *Relation) Includes(names ...any) *Relation
- func (r *Relation) IncludesNames() []string
- func (r *Relation) Joins(names ...any) *Relation
- func (r *Relation) Last() *Relation
- func (r *Relation) LastRecord(a Adapter) (*Record, error)
- func (r *Relation) LeftJoins(names ...any) *Relation
- func (r *Relation) Limit(n int) *Relation
- func (r *Relation) MaximumSQL(col string) string
- func (r *Relation) Merge(other *Relation) *Relation
- func (r *Relation) MinimumSQL(col string) string
- func (r *Relation) Not(cond ...any) *Relation
- func (r *Relation) Offset(n int) *Relation
- func (r *Relation) Or(other *Relation) *Relation
- func (r *Relation) Order(cols ...any) *Relation
- func (r *Relation) Pluck(a Adapter, cols ...any) ([][]any, error)
- func (r *Relation) PluckSQL(cols ...any) string
- func (r *Relation) Scope(name string) *Relation
- func (r *Relation) Select(cols ...any) *Relation
- func (r *Relation) SumSQL(col string) string
- func (r *Relation) Take() *Relation
- func (r *Relation) TakeRecord(a Adapter) (*Record, error)
- func (r *Relation) ToArray(a Adapter) ([]*Record, error)
- func (r *Relation) ToSQL() string
- func (r *Relation) UpdateAllSQL(sets map[string]any) string
- func (r *Relation) Where(cond ...any) *Relation
- type Row
- type SaveOption
- type StatementCache
- type Substitute
- type Symbol
- type TableDef
- func (t *TableDef) Column(name, typ string, opts ...ColOpt) *TableDef
- func (t *TableDef) NoPrimaryKey() *TableDef
- func (t *TableDef) PrimaryKey(name string) *TableDef
- func (t *TableDef) References(name string, opts ...ColOpt) *TableDef
- func (t *TableDef) Timestamps() *TableDef
- func (t *TableDef) ToSQL() string
- type Value
Constants ¶
This section is empty.
Variables ¶
var ErrAbort = errors.New("activerecord: callback chain halted")
ErrAbort is the sentinel a before_* callback returns to halt the chain, the pure-Go equivalent of ActiveRecord's `throw :abort`. A halted lifecycle makes the triggering persistence method return (false, nil): a soft failure, not an error.
var ErrRollback = errors.New("activerecord: transaction rollback")
ErrRollback is the pure-Go equivalent of `raise ActiveRecord::Rollback`: returning it from a Transaction block rolls that transaction back but is not re-raised to the caller (Transaction returns nil).
Functions ¶
func AddColumnSQL ¶
AddColumnSQL renders ALTER TABLE ... ADD "col" type (add_column).
func AddForeignKeySQL ¶
AddForeignKeySQL renders ALTER TABLE ... ADD CONSTRAINT ... FOREIGN KEY, matching add_foreign_key's default constraint name and column convention.
func AddIndexSQL ¶
AddIndexSQL renders CREATE [UNIQUE] INDEX. The index name defaults to ActiveRecord's "index_<table>_on_<cols>" convention.
func AddTimestampsSQL ¶
AddTimestampsSQL renders the two ALTER TABLE … ADD statements add_timestamps issues (created_at, updated_at as NOT NULL datetimes).
func ChangeColumnNullSQL ¶
ChangeColumnNullSQL renders the ALTER that toggles a column's NOT NULL constraint (change_column_null). Postgres uses SET/DROP NOT NULL; the other dialects use the MODIFY form.
func Count ¶
Count runs the relation's COUNT(*) through the adapter and returns the scalar. The single result row's single column is coerced to int64.
func Delete ¶
Delete removes the record's row with a single DELETE and no callbacks or transaction, matching ActiveRecord's record.delete.
func Destroy ¶
Destroy deletes the record's row through the adapter inside a transaction, running the destroy callbacks (before_destroy → DELETE → after_destroy). It reports success and any error; a halted before_destroy returns (false, nil).
func DropTableSQL ¶
DropTableSQL renders DROP TABLE (drop_table).
func Exists ¶
Exists runs the relation's existence probe through the adapter and reports whether a matching row exists (the execution half of exists?). It is the canonical wiring a uniqueness validator's callback uses.
func Pluralize ¶
Pluralize returns the plural form of a lowercase singular English word using ActiveSupport's default inflection rules (the subset a Rails model name exercises): the uncountable and irregular sets first, then the common suffix rules ("y"->"ies" after a consonant, "s"/"x"/"z"/"ch"/"sh"->"es", "o"->"oes" after a consonant), falling back to appending "s". Input is assumed already underscored/lowercased (Tableize's path); a trailing pluralization is a host concern in the query core, so this is the one place that owns it.
func Preload ¶
Preload eager-loads the named association for a set of parent records with a single additional query (per hop), attaching the results to each parent. It is a no-op when parents is empty or the association is unknown.
func RemoveColumnSQL ¶
RemoveColumnSQL renders ALTER TABLE … DROP COLUMN (remove_column), the ANSI form postgres/mysql emit.
func RemoveIndexSQL ¶
RemoveIndexSQL renders DROP INDEX (remove_index). The index name defaults to ActiveRecord's index_<table>_on_<cols> convention when not given.
func RenameColumnSQL ¶
RenameColumnSQL renders ALTER TABLE … RENAME COLUMN … TO … (rename_column).
func Save ¶
func Save(a Adapter, rec *Record, opts ...SaveOption) (bool, error)
Save inserts a new record or updates a changed one through the adapter, running the validation and callback lifecycle in a transaction. It returns whether the record was saved (false on a validation failure or a halted before_* callback, with no error) and any database or callback error.
The lifecycle mirrors ActiveRecord's save:
before_validation → validate → after_validation (outside the transaction) BEGIN before_save → before_(create|update) → INSERT/UPDATE → after_(create|update) → after_save COMMIT after_commit (or after_rollback)
func SchemaMigrationsTableSQL ¶
SchemaMigrationsTableSQL renders the CREATE TABLE for ActiveRecord's schema_migrations bookkeeping table.
func Tableize ¶
Tableize returns the table name ActiveRecord infers for a class name: the demodulized name underscored and pluralized ("User" -> "users", "LineItem" -> "line_items", "Admin::Account" -> "accounts"). It is the inference ActiveRecord::Base does when a model does not set table_name.
func Transaction ¶
Transaction runs fn inside a database transaction on the connection, opening a real transaction at the top level and a SAVEPOINT when already nested. It commits (or releases the savepoint) when fn returns nil, and rolls back when fn returns an error or panics. ErrRollback rolls back and is swallowed; any other error rolls back and propagates.
func TransactionDepth ¶
TransactionDepth reports how many transactions/savepoints are currently open on the connection (0 when none). It is exposed for hosts and tests that assert nesting.
Types ¶
type Adapter ¶
type Adapter interface {
// Execute runs a statement that returns rows (a SELECT / ExistsSQL probe)
// and yields them in order.
Execute(sql string) ([]Row, error)
// ExecuteDML runs an INSERT/UPDATE/DELETE and returns the affected row
// count (and the last insert id where the driver provides it).
ExecuteDML(sql string) (affected int64, lastInsertID int64, err error)
// AdapterName reports the driver's ActiveRecord adapter name, used to pick
// the [Dialect] ("sqlite3", "postgresql", "mysql2").
AdapterName() string
}
Adapter is the host seam through which this deterministic core reaches a real database. A host wires an implementation backed by go-ruby-sqlite3 or go-ruby-pg (or any driver) and this package hands it the SQL strings it renders; the actual execution, connection pooling and transactions live in the host. Keeping execution behind this interface is what makes the SQL-generation core 100% Ruby- and CGO-free and byte-for-byte testable against the ActiveRecord oracle.
Row is one result row as an ordered column=>value map; the host materializes these into [Record]s via Model.Load.
type AssocOpt ¶
type AssocOpt func(*Association)
AssocOpt configures an association.
func AssociationForeignKey ¶
AssociationForeignKey overrides the HABTM other-side key column.
type Association ¶
type Association struct {
Kind AssocKind
// Name is the association name ("posts", "company").
Name string
// ClassName is the target model's Ruby class name ("Post"). For :through it
// is the final target.
ClassName string
// ForeignKey overrides the default foreign-key column.
ForeignKey string
// Through, when set, names the intermediate association (has_many :through /
// has_one :through).
Through string
// JoinTable overrides the HABTM join-table name.
JoinTable string
// AssociationForeignKey overrides the HABTM other-side key.
AssociationForeignKey string
}
Association describes one declared association on a model.
type Callback ¶
Callback is a lifecycle hook body. It receives the record and returns nil to continue, ErrAbort to halt a before_* chain (soft failure), or any other error to abort the operation with that error.
type ColOpt ¶
type ColOpt func(*colDef)
ColOpt configures a column in a table definition.
type Column ¶
Column is one column of a model's table: its name and its logical type (used for DDL emission and attribute type-casting). Type is an ActiveRecord type symbol name ("string", "integer", "boolean", "datetime", …).
type Dialect ¶
type Dialect int
Dialect selects identifier quoting and value literalization so the emitted SQL is byte-faithful to what the matching ActiveRecord adapter produces.
const ( // SQLite mirrors ActiveRecord's sqlite3 adapter: double-quoted identifiers, // booleans as TRUE/FALSE, strings single-quoted with ” escaping. SQLite Dialect = iota // Postgres mirrors ActiveRecord's postgresql adapter: double-quoted // identifiers, booleans as TRUE/FALSE, blobs as bytea hex. Postgres // MySQL mirrors ActiveRecord's mysql2/trilogy adapter: backtick-quoted // identifiers, booleans as 1/0, backslash-escaped strings. MySQL )
func DialectByName ¶
DialectByName maps an ActiveRecord adapter name to a Dialect. Unknown names map to SQLite (the deterministic default used by the oracle).
func DialectFor ¶
DialectFor returns the Dialect matching an adapter's AdapterName.
type Errors ¶
type Errors struct {
// contains filtered or unexported fields
}
Errors is the pure-Go shape of ActiveModel::Errors: per-attribute message lists plus the full_messages rendering ("Attr message"). Attributes and messages are kept in declaration/insertion order to match ActiveRecord.
func (*Errors) Add ¶
Add records a message for an attribute (ActiveModel::Errors#add), preserving first-seen attribute order.
func (*Errors) FullMessages ¶
FullMessages returns the "Humanized attr message" list, in attribute insertion order, matching ActiveModel::Errors#full_messages.
type LengthOpts ¶
LengthOpts configures a length validator (nil field = unset).
type Migrator ¶
type Migrator struct {
// contains filtered or unexported fields
}
Migrator runs schema migrations through an Adapter, recording applied versions in schema_migrations so migrations are idempotent, mirroring ActiveRecord::Migrator.
func NewMigrator ¶
NewMigrator returns a Migrator bound to the adapter's connection and dialect.
func (*Migrator) AppliedVersions ¶
AppliedVersions returns the migration versions already recorded, in the order the adapter returns them.
func (*Migrator) EnsureSchemaMigrations ¶
EnsureSchemaMigrations creates the schema_migrations table once per migrator.
type Model ¶
type Model struct {
// Name is the Ruby class name ("User"), used only for validation messages
// and diagnostics.
Name string
// TableName is the resolved SQL table name ("users").
TableName string
// PrimaryKey is the primary-key column name ("id").
PrimaryKey string
// Dialect selects SQL rendering; defaults to SQLite (zero value).
Dialect Dialect
// contains filtered or unexported fields
}
Model describes a mapped ActiveRecord class: its table name, primary key, columns, associations and validations. A host builds one per Ruby model class and hands it to Model.All (or the Where/Order/… shortcuts) to obtain a Relation, and to Model.Build to obtain a validating attribute record.
TableName defaults to the pluralized, underscored class name in Rails; the host supplies the already-resolved table name (pluralization is a host concern), matching how a differential oracle names its tables.
func NewModel ¶
NewModel returns a Model for class name with the given table and columns. The primary key defaults to "id".
func (*Model) AddColumn ¶
AddColumn appends a column (chainable), for hosts that describe the schema incrementally.
func (*Model) AfterCommit ¶
AfterCommit registers an after_commit callback (runs once the outermost transaction commits).
func (*Model) AfterCreate ¶
AfterCreate registers an after_create callback.
func (*Model) AfterDestroy ¶
AfterDestroy registers an after_destroy callback.
func (*Model) AfterRollback ¶
AfterRollback registers an after_rollback callback (runs when the transaction rolls back).
func (*Model) AfterUpdate ¶
AfterUpdate registers an after_update callback.
func (*Model) AfterValidation ¶
AfterValidation registers an after_validation callback.
func (*Model) All ¶
All returns a Relation over the model (ActiveRecord's Model.all), with the model's default_scope and single-table-inheritance type condition applied — the baseline every Model shortcut (Where/Order/…) starts from. Use Model.Unscoped to obtain a relation with neither.
func (*Model) Association ¶
func (m *Model) Association(name string) *Association
Association returns the named association, or nil.
func (*Model) BeforeCreate ¶
BeforeCreate registers a before_create callback.
func (*Model) BeforeDestroy ¶
BeforeDestroy registers a before_destroy callback.
func (*Model) BeforeSave ¶
BeforeSave registers a before_save callback (runs for both create and update).
func (*Model) BeforeUpdate ¶
BeforeUpdate registers a before_update callback.
func (*Model) BeforeValidation ¶
BeforeValidation registers a before_validation callback.
func (*Model) BelongsTo ¶
BelongsTo declares a belongs_to association. className defaults from name (host handles classification when it differs) — here name is also used as the class-name stem via [singularizeClass].
func (*Model) Build ¶
Build returns a new Record with the given initial attributes (Model.new), type-cast per column. A newly-built record has every set attribute considered changed (no persisted original), matching ActiveRecord.
func (*Model) Columns ¶
Columns returns the model's columns in declaration order. The slice must not be mutated.
func (*Model) Create ¶
Create builds a record from attrs and saves it, returning the record (whose Record.IsPersisted reports success) and any error, matching Model.create.
func (*Model) DefaultScope ¶
DefaultScope registers the model's default_scope: a refinement applied to every relation started with Model.All (and the Where/Order/… shortcuts). Model.Unscoped bypasses it. Registering twice replaces the previous one, matching a single default_scope declaration.
func (*Model) FindByRecord ¶
FindByRecord returns the first record matching the hash conditions, or nil (Model.find_by). The conditions are applied in sorted key order for a deterministic single query.
func (*Model) FindByStatement ¶
func (m *Model) FindByStatement(attrs ...string) *PreparedStatement
FindByStatement returns the cached prepared statement for Model.find_by over the given attribute names (order-significant): SELECT … WHERE a = ? AND b = ? … LIMIT ?, binding the supplied values then 1.
func (*Model) FindRecord ¶
FindRecord looks up a row by primary key through the cached prepared statement and returns the record, or nil when not found (Model.find, minus the raise).
func (*Model) FindStatement ¶
func (m *Model) FindStatement() *PreparedStatement
FindStatement returns the cached prepared statement for Model.find(id): SELECT … WHERE pk = ? LIMIT ?, binding [id, 1].
func (*Model) InsertSQL ¶
InsertSQL renders an INSERT for one row of attributes, columns in sorted order for determinism: INSERT INTO "table" ("a", "b") VALUES (v1, v2).
func (*Model) Load ¶
Load returns a Record whose attributes are treated as persisted (loaded from the database): no attribute is changed until a subsequent Set, matching a row materialized by ActiveRecord.
func (*Model) LoadSTI ¶
LoadSTI materializes a row as the subclass named by its type column when the model is an STI root with that subclass registered; otherwise it loads the row as the receiver. It is the instantiation ActiveRecord does when reading rows from a base-class relation.
func (*Model) Register ¶
Register links a sibling model so association joins can resolve the target table/keys. It is chainable and idempotent.
func (*Model) STI ¶
STI marks the model as a single-table-inheritance root discriminated by column (defaulting to "type"). The base class queries every row (no type filter); subclasses created with Model.Subclass add the filter. The column is added to the model if absent.
func (*Model) Scope ¶
Scope registers a named scope: a function that refines a Relation. Calling Relation.Scope (or the generated shortcut a host wires) applies it.
func (*Model) ScopeNames ¶
ScopeNames returns the registered named-scope names in sorted order.
func (*Model) Subclass ¶
Subclass returns a new model for an STI subclass named className: it shares the root's table, primary key, dialect, columns, associations and sibling registry, carries className as its type value, and is filtered by that value in queries. The subclass is registered so the root (and every ancestor) can instantiate and filter it.
func (*Model) Unscoped ¶
Unscoped returns a bare relation that ignores the model's default_scope and STI type condition (ActiveRecord's Model.unscoped), the escape hatch for querying every row of the table.
func (*Model) Validate ¶
Validate runs every validator against rec and returns the collected Errors.
func (*Model) ValidatesExclusion ¶
ValidatesExclusion adds an exclusion validator (validates :attr, exclusion:{in:list}).
func (*Model) ValidatesFormat ¶
ValidatesFormat adds a format validator (validates :attr, format:{with:re}).
func (*Model) ValidatesInclusion ¶
ValidatesInclusion adds an inclusion validator (validates :attr, inclusion:{in:list}).
func (*Model) ValidatesLength ¶
func (m *Model) ValidatesLength(attr string, o LengthOpts) *Model
ValidatesLength adds a length validator (validates :attr, length:{...}).
func (*Model) ValidatesNumericality ¶
func (m *Model) ValidatesNumericality(attr string, o NumericalityOpts) *Model
ValidatesNumericality adds a numericality validator.
func (*Model) ValidatesPresence ¶
ValidatesPresence adds a presence validator (validates :attr, presence:true).
func (*Model) ValidatesUniqueness ¶
ValidatesUniqueness adds a uniqueness validator. Uniqueness needs a database query, which is a host seam: the exists callback reports whether a conflicting row exists (the host runs Relation.ExistsSQL through its Adapter). When exists is nil the validator is skipped (documented).
type NumericalityOpts ¶
type NumericalityOpts struct {
OnlyInteger bool
GreaterThan *float64
GreaterThanOrEq *float64
LessThan *float64
LessThanOrEq *float64
EqualTo *float64
Other *float64 // other_than
Odd bool
Even bool
}
NumericalityOpts configures a numericality validator.
type PreparedAdapter ¶
type PreparedAdapter interface {
Adapter
// ExecutePrepared runs a prepared statement with positional bind values.
ExecutePrepared(sql string, binds []any) ([]Row, error)
}
PreparedAdapter is the optional host seam for true driver-level prepared statements. An Adapter that also implements it receives the SQL template and the ordered bind values, keeping the binds out of the SQL string.
type PreparedStatement ¶
type PreparedStatement struct {
// SQL is the template with dialect bind markers.
SQL string
// contains filtered or unexported fields
}
PreparedStatement is a cached SQL template plus its ordered bind slots. It is immutable and safe to reuse across calls and goroutines.
func (*PreparedStatement) Execute ¶
func (s *PreparedStatement) Execute(a Adapter, supplied ...any) ([]*Record, error)
Execute runs the statement with the supplied bind values and materializes the result rows into persisted records. A PreparedAdapter host gets a true prepared execution; a plain Adapter gets the binds inlined into the SQL.
func (*PreparedStatement) ExecuteOne ¶
func (s *PreparedStatement) ExecuteOne(a Adapter, supplied ...any) (*Record, error)
ExecuteOne runs the statement and returns the first materialized record, or nil when no row matched (the shape find/find_by consume).
type Range ¶
Range models a Ruby Range used as a where value (col: a..b), rendered to BETWEEN (inclusive) or the half-open form ActiveRecord emits for exclusive ranges. A nil Begin/End models a beginless/endless range.
type Record ¶
type Record struct {
// contains filtered or unexported fields
}
Record is a single model instance's attribute set with dirty tracking: it holds the current values and the values loaded from the database, so Changed/Changes report modifications the way ActiveModel::Dirty does. Values are type-cast to the column type on write (Set).
func LoadAll ¶
LoadAll runs the relation's SELECT through the adapter and materializes each row into a persisted Record.
func LoadIncludes ¶
LoadIncludes runs the relation's main SELECT and then eager-loads every association named by Relation.Includes, attaching the targets to the loaded records. It returns the root records (with their associations preloaded).
func (*Record) AttributeChanged ¶
AttributeChanged reports whether one attribute changed (name_changed?).
func (*Record) Attributes ¶
Attributes returns a copy of the current attribute map.
func (*Record) Changed ¶
Changed reports whether any attribute differs from its persisted original (ActiveModel::Dirty#changed?).
func (*Record) ChangedAttributeNames ¶
ChangedAttributeNames returns the changed attribute names (name order).
func (*Record) Changes ¶
Changes returns a map of changed attribute => {old, new}, matching ActiveModel::Dirty#changes.
func (*Record) Errors ¶
Errors returns the validation errors from the most recent Validate/Save/Valid call (an empty Errors set before any run), matching record.errors.
func (*Record) IsDestroyed ¶
IsDestroyed reports whether the record was destroyed (ActiveRecord's destroyed?).
func (*Record) IsNewRecord ¶
IsNewRecord reports whether the record has not yet been inserted (ActiveRecord's new_record?).
func (*Record) IsPersisted ¶
IsPersisted reports whether the record corresponds to a stored row (ActiveRecord's persisted?): true after Load or a successful insert, false for a freshly Built record and after Destroy.
func (*Record) PreloadedAssociation ¶
PreloadedAssociation returns the eager-loaded target records for the named association (empty when it was not preloaded), the pure-Go equivalent of reading an association whose target ActiveRecord has already cached.
func (*Record) SaveClean ¶
func (r *Record) SaveClean()
SaveClean snapshots the current attributes as the persisted baseline (what ActiveRecord does after a successful save): subsequent Changes are relative to now.
func (*Record) Set ¶
Set writes an attribute, type-casting to the column type. Unknown attributes are stored verbatim (ActiveRecord raises; a host may pre-filter). Returns the receiver for chaining.
func (*Record) Validate ¶
Validate runs the model's validators against this record and caches the result on the record (readable via Record.Errors, like record.errors after valid?).
type Relation ¶
type Relation struct {
// contains filtered or unexported fields
}
Relation is a lazy, immutable, chainable ActiveRecord::Relation. Every refining method (Where, Order, Limit, …) returns a new Relation, leaving the receiver unchanged, mirroring ActiveRecord's copy-on-refine semantics. Relation.ToSQL renders the accumulated relation to a SQL string that is byte-faithful to ActiveRecord's Relation#to_sql for the model's dialect.
func (*Relation) AverageSQL ¶
AverageSQL renders AVG("table"."col") (Model...average(:col)).
func (*Relation) Count ¶
Count runs COUNT(*) for the relation and returns the scalar (relation.count).
func (*Relation) CountColumnSQL ¶
CountColumnSQL renders COUNT("table"."col").
func (*Relation) CountSQL ¶
CountSQL renders the COUNT(*) query for the relation (Model...count), preserving where/join/group but dropping order and select, as ActiveRecord does for a count without a column.
func (*Relation) DeleteAllSQL ¶
DeleteAllSQL renders a DELETE for the relation's scope (Model...delete_all).
func (*Relation) Exists ¶
Exists runs the existence probe and reports whether any row matches (relation.exists?).
func (*Relation) ExistsSQL ¶
ExistsSQL renders the existence probe ActiveRecord emits for exists?: SELECT 1 AS one FROM "table" ... LIMIT 1.
func (*Relation) Find ¶
Find scopes to the row with the given primary-key value (Model.find(id)): WHERE "table"."id" = id LIMIT 1.
func (*Relation) FindBy ¶
FindBy scopes to the first row matching the hash conditions (Model.find_by(...)): the conditions plus LIMIT 1.
func (*Relation) FindEach ¶
FindEach loads the relation in primary-key-ordered batches of batchSize and calls fn for each record, stopping early if fn returns an error (relation.find_each). A non-positive batchSize defaults to 1000, matching ActiveRecord.
func (*Relation) First ¶
First returns a relation scoped to the first row: ORDER BY primary key ASC (when no order is set) LIMIT 1, matching Model.first.
func (*Relation) FirstRecord ¶
FirstRecord runs the relation scoped to its first row and returns it, or nil when empty (relation.first).
func (*Relation) From ¶
From overrides the FROM table name (ActiveRecord's Model.from("table")), keeping the model's column qualification. An empty name clears the override.
func (*Relation) Group ¶
Group appends GROUP BY columns (table-qualified bare names, raw strings passed through).
func (*Relation) Includes ¶
Includes records association names to eager-load when the relation is materialized with LoadIncludes (ActiveRecord's includes/preload). It is chainable and copy-on-write like every relation refinement.
func (*Relation) IncludesNames ¶
IncludesNames returns the association names queued for eager loading.
func (*Relation) Joins ¶
Joins adds INNER JOINs for the named associations (Symbol/string), rendering the join SQL ActiveRecord emits for belongs_to/has_many/has_one/HABTM/:through.
func (*Relation) Last ¶
Last returns a relation scoped to the last row: the order reversed (or primary key DESC absent an order) LIMIT 1, matching Model.last.
func (*Relation) LastRecord ¶
LastRecord runs the relation scoped to its last row and returns it, or nil (relation.last).
func (*Relation) MaximumSQL ¶
MaximumSQL renders MAX("table"."col") (Model...maximum(:col)).
func (*Relation) Merge ¶
Merge combines another relation's where/having/order/group/joins into the receiver (ActiveRecord's relation.merge), appending its clauses.
func (*Relation) MinimumSQL ¶
MinimumSQL renders MIN("table"."col") (Model...minimum(:col)).
func (*Relation) Not ¶
Not adds negated hash conditions (ActiveRecord's where.not). Only the hash form is supported (matching the common where.not(col: v) usage).
func (*Relation) Or ¶
Or ORs the receiver's where-clause with another relation's, matching ActiveRecord's relation.or(other): the two predicate groups are parenthesized and joined by OR. Non-where clauses come from the receiver.
func (*Relation) Order ¶
Order appends ordering terms. A bare name orders ASC; a map[string]any of name=>"desc"/"asc" (or Symbol values) sets direction; a raw string with a space is passed through.
func (*Relation) Pluck ¶
Pluck runs the pluck SELECT and returns, per row, the requested column values in order (relation.pluck(:a, :b)). Values are read from the result rows by their bare column names, as adapters key them.
func (*Relation) PluckSQL ¶
PluckSQL renders the SELECT for plucking the given columns (Model...pluck(:a,:b)): the qualified columns, keeping where/join/order but no star.
func (*Relation) Select ¶
Select sets the projection. Bare column names (string/Symbol) are table-qualified and quoted; a string that is not a plain identifier (contains a space, paren, dot or "*") is treated as a raw SQL expression and passed through, matching ActiveRecord.
func (*Relation) Take ¶
Take returns a relation with just LIMIT 1 and no imposed order (Model.take).
func (*Relation) TakeRecord ¶
TakeRecord runs the relation with LIMIT 1 and returns a row without imposing an order, or nil (relation.take).
func (*Relation) ToArray ¶
ToArray runs the relation's SELECT and returns the materialized records (ActiveRecord's to_a / load).
func (*Relation) ToSQL ¶
ToSQL renders the relation to a SELECT statement, byte-faithful to ActiveRecord's Relation#to_sql for the model's dialect.
func (*Relation) UpdateAllSQL ¶
UpdateAllSQL renders an UPDATE for the relation's scope, SET assignments in sorted column order (Model...update_all(a: 1)).
func (*Relation) Where ¶
Where refines the relation. It accepts, matching ActiveRecord:
- a Hash-like map (map[string]any) — column => value, rendered as equality / IN / BETWEEN / IS NULL and AND-joined and table-qualified.
- a single string — a raw SQL fragment, wrapped in parens.
- a string with "?" placeholders followed by bind values — each "?" substituted by the quoted value.
- a string with ":name" placeholders followed by one map of binds.
The receiver is unchanged; a new Relation is returned.
type SaveOption ¶
type SaveOption func(*saveConfig)
SaveOption configures Save/Create.
func WithoutValidation ¶
func WithoutValidation() SaveOption
WithoutValidation skips validations for this write (save(validate: false)).
type StatementCache ¶
type StatementCache struct {
// contains filtered or unexported fields
}
StatementCache memoizes prepared statements by a string key (the query shape), mirroring the per-model statement cache ActiveRecord keeps for find/find_by.
func NewStatementCache ¶
func NewStatementCache() *StatementCache
NewStatementCache returns an empty statement cache.
func (*StatementCache) Fetch ¶
func (c *StatementCache) Fetch(key string, build func() *PreparedStatement) *PreparedStatement
Fetch returns the cached statement for key, building and caching it with build on a miss (ActiveRecord's StatementCache.create-then-cache pattern).
type Substitute ¶
type Substitute struct{}
Substitute is ActiveRecord's bind placeholder (StatementCache::Substitute, i.e. `params.bind`): it marks where a value will be supplied at execute time rather than baked into the template.
type Symbol ¶
type Symbol string
Symbol is a Ruby Symbol (`:name`), used for column and association names as a host may hand them over. Its string form is the bare name.
type TableDef ¶
type TableDef struct {
// contains filtered or unexported fields
}
TableDef accumulates a create_table definition, emitting the CREATE TABLE DDL ActiveRecord's schema statements produce for the dialect.
func CreateTable ¶
CreateTable begins a create_table definition. By default an "id" integer primary key is added (ActiveRecord's default), matching create_table :name.
func (*TableDef) NoPrimaryKey ¶
NoPrimaryKey disables the implicit primary key (create_table id:false).
func (*TableDef) PrimaryKey ¶
PrimaryKey sets the primary-key column name (create_table primary_key: :name / id: :name), replacing the default "id".
func (*TableDef) References ¶
References adds a "<name>_id" bigint foreign-key column (t.references).
func (*TableDef) Timestamps ¶
Timestamps adds created_at/updated_at NOT NULL datetime columns (t.timestamps), matching ActiveRecord's precision-6 datetimes.
