class Rotor::HasMany[T <: Rotor::Model]
include Enumerable[T]
A model's has_many association, as its getter gives it (user.posts):
the associated models once preloaded (Rotor::Repo#preload), and the
query that finds them either way. There is no lazy loading: reading
the models of one not preloaded raises Rotor::NotLoadedError.
class HUser < Rotor::Model
table "users" do
column :id, Int, primary: true
has_many HPost, name: :posts, foreign_key: :user_id
end
end
class HPost < Rotor::Model
table "posts" do
column :id, Int, primary: true
column :user_id, Int
column :published, Bool, default: false
end
end
u = HUser.load({id: 7})
u.posts.loaded? # => false
u.posts.query.to_sql # => ["SELECT \"id\", \"user_id\", \"published\" FROM \"posts\" WHERE \"user_id\" = $1", [7]]
u.posts.query.where { published }.to_sql[0] # => "SELECT \"id\", \"user_id\", \"published\" FROM \"posts\" WHERE \"user_id\" = $1 AND \"published\""
/home/runner/work/rotor/rotor/src/association.qz:27
Class methods
def self.new(target: Type[T], owner: String, name: Symbol, foreign_key: Symbol, key_column: Symbol?, key: Int | Float | String | Bool | Time | Bytes | Nil, models: Array[Rotor::Model]?, through: [Type[Object], Rotor::Association]? = …) -> Rotor::HasMany[T]
(Made by the getter has_many generates.)
def self.foreign_key!(target: Type[Rotor::Model], fk: Symbol, owner: String, name: Symbol) -> Void
Raises unless target has the column fk (an association's key,
checked when a query or a preload uses it: the target's table may
run after the association's).
Methods
def loaded? -> Bool
Whether the models were preloaded.
def target -> Type[T]
The associated model's class.
def each(&: (T) -> Void) -> Void
Calls the block with each model; raises Rotor::NotLoadedError when
they were not preloaded.
def size -> Int
How many models there are (preloaded).
def empty? -> Bool
Whether there is none (preloaded).
def to_a -> Array[T]
The models, in an array (preloaded).
def query -> Rotor::Query[T]
The association as a query: the target's rows whose foreign key is
this model's key, to refine (posts.query.where { published }) and
run (repo.all(user.posts.query)); through a join model, the
target's rows the join model's rows pair with this one, by a
subquery ("id" IN (SELECT "tag_id" FROM "post_tags" WHERE "post_id" = $1): each once). Raises Rotor::SchemaError when the target has
no such column (or the join model no such belongs_to),
Rotor::MissingAttributeError when the model's key is not set.
def inspect -> String
A developer-readable representation, as p prints it: strings quoted,
collections with their elements' inspect, an object with its fields
(#<Point @x=1, @y=2>).
from Object
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