class Rotor::Model

The base class of a model: a row of a table, with typed accessors that its table block generates when the program is compiled.

class DocUser < Rotor::Model
  table "users" do
    column :id, Int, primary: true
    column :name, String
    column :email, String, null: true
    column :age, Int, default: 0
    timestamps
  end
end

u = DocUser.new(name: "Ann")   # DocUser.new(name: 1) does not compile
u.name     # => "Ann"
u.email    # => nil
u.age      # => 0
u.changed  # => [:name]
v = u.with(email: "ann@example.com", age: 41)
v.age      # => 41
u.age      # => 0
DocUser.table_name  # => "users"
DocUser.columns.map { |c| c.name }  # => [:id, :name, :email, :age, :created_at, :updated_at]

A model is an immutable value, Shareable: with(col: value, ...) gives a new one with those columns changed (each column an optional keyword typed by it), which remembers the columns assigned since it was made or loaded (changed): the columns an update writes. A model's new takes the columns as with does (the same keywords, all optional), starting from the columns' defaults, and remembers those given as changed; load(values) makes one from a row's values, unchanged. A model class cannot declare a var field (it is Shareable), and does not write initialize: table generates its constructors.

The columns are declared in one block because a class body's statements run independently of each other (Quarz's docs/14 §2): no statement sees what another generates, so the one table statement is what knows every column, for columns and primary_key.

/home/runner/work/rotor/rotor/src/model.qz:48

Class methods

def self.defaults(info: Rotor::TableInfo) -> Hash[Symbol, Int | Float | String | Bool | Time | Bytes | Nil]

The columns' defaults.

/home/runner/work/rotor/rotor/src/model.qz:82

static def self.table(name: String? = …, &block: Rotor::Schema.() -> Void) -> Void

Declares the model's table and its columns (Rotor::Schema), and generates the typed accessors, the constructors (new of the columns as optional keywords, and of a Checkpoint, which restore makes), with, and the class's metadata: columns, table_name (name, by default the class's name in snake_case, plural), primary_key and associations. A class has one table block.

/home/runner/work/rotor/rotor/src/model.qz:98

def self.columns -> Array[Rotor::Column]

The columns, in order (generated by table).

/home/runner/work/rotor/rotor/src/model.qz:163

def self.table_name -> String

The table's name (generated by table).

/home/runner/work/rotor/rotor/src/model.qz:165

def self.primary_key -> Symbol?

The primary key's column, or nil for none (generated by table).

/home/runner/work/rotor/rotor/src/model.qz:167

def self.associations -> Array[Rotor::Association]

The associations, in order (generated by table).

/home/runner/work/rotor/rotor/src/model.qz:169

def self.table_info -> Rotor::TableInfo

The table's name, columns and primary key (generated by table).

/home/runner/work/rotor/rotor/src/model.qz:171

def self.blank -> Self

A new model of this class: new, the columns' defaults set (Rotor::Changeset.cast of a class).

/home/runner/work/rotor/rotor/src/model.qz:182

def self.query -> Rotor::Query[Self]

Every row, as a query (Rotor::Query), to refine.

/home/runner/work/rotor/rotor/src/model.qz:185

def self.preload(&spec: Quoted[shareable Self.() -> Object]) -> Rotor::Query[Self]

query.preload: every row, with the associations the block names preloaded.

/home/runner/work/rotor/rotor/src/model.qz:193

def self.where(&cond: Quoted[shareable Self.() -> Bool]) -> Rotor::Query[Self]

query.where: the rows for which the block is true.

/home/runner/work/rotor/rotor/src/model.qz:196

def self.where(&cond: Quoted[shareable (Self) -> Bool]) -> Rotor::Query[Self]

query.where: the rows for which the block is true.

/home/runner/work/rotor/rotor/src/model.qz:199

def self.filter(&cond: Quoted[shareable (Self) -> Bool]) -> Rotor::Query[Self]

query.filter.

/home/runner/work/rotor/rotor/src/model.qz:202

def self.order(&key: Quoted[shareable Self.() -> Object]) -> Rotor::Query[Self]

query.order.

/home/runner/work/rotor/rotor/src/model.qz:205

def self.order(&key: Quoted[shareable (Self) -> Object]) -> Rotor::Query[Self]

query.order.

/home/runner/work/rotor/rotor/src/model.qz:208

def self.select[R](&f: Quoted[shareable Self.() -> R]) -> Rotor::Query[R]

query.select.

/home/runner/work/rotor/rotor/src/model.qz:211

def self.select[R](&f: Quoted[shareable (Self) -> R]) -> Rotor::Query[R]

query.select.

/home/runner/work/rotor/rotor/src/model.qz:214

def self.map[R](&f: Quoted[shareable (Self) -> R]) -> Rotor::Query[R]

query.map.

/home/runner/work/rotor/rotor/src/model.qz:217

def self.count -> Rotor::Query[Int]

query.count.

/home/runner/work/rotor/rotor/src/model.qz:220

def self.exists -> Rotor::Query[Bool]

query.exists.

/home/runner/work/rotor/rotor/src/model.qz:223

def self.first -> Rotor::Query[Self]

query.first.

/home/runner/work/rotor/rotor/src/model.qz:226

def self.limit(n: Int) -> Rotor::Query[Self]

query.limit(n).

/home/runner/work/rotor/rotor/src/model.qz:229

def self.find_column(name: Symbol) -> Rotor::Column?

The column name, or nil for none.

/home/runner/work/rotor/rotor/src/model.qz:232

def self.load(values: Hash[Symbol, Object?]) -> Self

A model of this class with the given values, unchanged: as read from a row. Each key must be a column, and each value of the column's type (or nil where the column admits NULL); the columns not given keep their defaults.

/home/runner/work/rotor/rotor/src/model.qz:238

def self.load_partial(values: Hash[Symbol, Object?]) -> Self

A model with only the given columns loaded (a select fetched them): reading another raises Rotor::NotLoadedError.

/home/runner/work/rotor/rotor/src/model.qz:242

def self.rebuild(m: Rotor::Model) -> Self

A model of this class made of m's values (m one of this class): how an association gives its models typed.

/home/runner/work/rotor/rotor/src/model.qz:332

def self.value(v: Object?) -> Int | Float | String | Bool | Time | Bytes | Nil

v as a column's value (checked against its column before).

/home/runner/work/rotor/rotor/src/model.qz:343

def self.own_table!(klass: Type[Object], owner: Type[Object], owner_name: String) -> Void

Raises unless klass is owner (named owner_name), the class whose table generated the member called (the class itself, by equal?, which no class can redefine, as == can be): a subclass that inherits a table is refused at its first use (the members with among them are its parent's).

/home/runner/work/rotor/rotor/src/model.qz:402

def self.no_table_of(model: String) -> String

The message for a model without a table block.

/home/runner/work/rotor/rotor/src/model.qz:408

def self.key_of(m: Rotor::Model, key: Symbol?) -> Int | Float | String | Bool | Time | Bytes | Nil

The value of m's column key (a key, primary or foreign), nil for none or not set; raises Rotor::NotLoadedError when a query did not fetch it.

/home/runner/work/rotor/rotor/src/model.qz:439

def self.belonging[T <: Rotor::Model](target: Type[T], m: Rotor::Model, name: Symbol, fk: Symbol) -> T?

What a belongs_to getter gives (association).

/home/runner/work/rotor/rotor/src/model.qz:455

Methods

def table_info -> Rotor::TableInfo

The table's name, columns and primary key, as the class's (generated by table).

/home/runner/work/rotor/rotor/src/model.qz:175

def restore(point: Rotor::Checkpoint) -> Self

A model of this class made of point.

/home/runner/work/rotor/rotor/src/model.qz:178

def read(name: Symbol) -> Object?

The value of column name (nil for one not set that admits it).

/home/runner/work/rotor/rotor/src/model.qz:245

def to_h -> Hash[Symbol, Int | Float | String | Bool | Time | Bytes | Nil]

The model's values by column, those set only: a column without a default that was never assigned is left out.

/home/runner/work/rotor/rotor/src/model.qz:252

def changed -> Array[Symbol]

The columns assigned since the model was made or loaded, in the order of their first assignment (one with's in the columns' order).

/home/runner/work/rotor/rotor/src/model.qz:256

def changed? -> Bool

Whether a column was assigned since.

/home/runner/work/rotor/rotor/src/model.qz:259

def keep_changes(names: Array[Symbol]) -> Self

The model with only the assignments of names kept (after the others were saved).

/home/runner/work/rotor/rotor/src/model.qz:263

def clear_changes -> Self

The model with the assignments forgotten: after it was saved.

/home/runner/work/rotor/rotor/src/model.qz:268

def with_values(values: Hash[Symbol, Object?]) -> Self

A copy with the columns of values set, each checked against its column's type, which remembers them as changed: what with does, for code that names the columns at run time (the repository's timestamps).

/home/runner/work/rotor/rotor/src/model.qz:274

def loaded(values: Hash[Symbol, Object?], *, partial: Bool = …) -> Self

The model with the values read from a row (load), checked, and no assignment; partial: when they are only those a query fetched (load_partial), without the defaults.

/home/runner/work/rotor/rotor/src/model.qz:307

def checkpoint -> Rotor::Checkpoint

What the model is made of.

/home/runner/work/rotor/rotor/src/model.qz:315

def preloaded(name: Symbol) -> Array[Rotor::Model]?

The models preloaded for the association name, or nil when it was not (Rotor::Repo#preload).

/home/runner/work/rotor/rotor/src/model.qz:319

def with_preloaded(assocs: Hash[Symbol, Array[Rotor::Model]]) -> Self

The model with the associations of assocs preloaded (each by name, the others kept).

/home/runner/work/rotor/rotor/src/model.qz:323

def nest[T <: Rotor::Model](association: Rotor::HasMany[T], &: T.() -> Object) -> Object?

Preloading names associations: nest(posts) { comments } names posts and, of each post, comments (Rotor::Repo#preload). Run outside a preload, it gives nil.

/home/runner/work/rotor/rotor/src/model.qz:337

def nest[T <: Rotor::Model](association: T?, &: T.() -> Object) -> Object?

Preloading names associations: nest(posts) { comments } names posts and, of each post, comments (Rotor::Repo#preload). Run outside a preload, it gives nil.

/home/runner/work/rotor/rotor/src/model.qz:340

def inspect -> String

#<User id: 1, name: "Ann", password: **redacted**>: a column declared redact: true hidden.

/home/runner/work/rotor/rotor/src/model.qz:353

def to_s -> String

The value as a string, for puts and interpolation. For an instance of a class, the class name in the form #<Point>; for an exception, its message; for a data value or an enum variant, the default inspect. It does not call an inspect the class defines.

from Object

/home/runner/work/rotor/rotor/src/model.qz:358

def fetched?(name: Symbol) -> Bool

Whether the column name was fetched (all were, but for a model a select loaded).

/home/runner/work/rotor/rotor/src/model.qz:449