class
CQL::ActiveRecord::Relations::Collection(Target, Pk)
- CQL::ActiveRecord::Relations::Collection(Target, Pk)
- Reference
- Object
Overview
Collection for one-to-many relationships.
This class manages the relationship between two tables through a foreign key column in the target table and provides methods to manage the association between the two tables and query records in the associated table based on the foreign key value of the parent record.
- param : Target (CQL::ActiveRecord::Model) - The target model
- param : Pk - The parent's primary key type
has_many returns one, for example has_many :posts, Post, foreign_key: :user_id in User:
user.posts.create(title: "Hello World")
user.posts.size # => 1
Included Modules
- CQL::ActiveRecord::Relations::BaseRelation
- Enumerable(Target)
Direct Known Subclasses
Defined in:
active_record/relations/collection.crConstructors
-
.new(key : Symbol, id : Pk, cascade : Bool = false, query base_query : CQL::Query | Nil = nil, auto_load : Bool = false, dependent : Symbol = :nullify)
Initialize the collection class for a one-to-many relationship - param : key (Symbol) - The foreign key in the target table (e.g., :user_id) - param : id (Pk) - The id value for the parent record - param : cascade (Bool) - Whether to delete associated records when parent is deleted (deprecated, use dependent) - param : query (CQL::Query) - Base query; the collection scopes it to the parent and operations run on clones of it - param : auto_load (Bool) - Whether to automatically load associated records - param : dependent (Symbol) - Dependency handling strategy - return : Collection(Target, Pk)
Instance Method Summary
-
#<<(record : Target)
Adds a record to the collection, as
#create(record)does. -
#[](index : Int32)
Get element at index, raises if out of bounds - param : index (Int32) - return : Target
-
#[]?(index : Int32)
Get element at index, returns nil if out of bounds - param : index (Int32) - return : Target?
-
#_inject_preloaded(records : Array(Target)) : Nil
Inject preloaded records without database query Used by eager loading/preload to set association data that was loaded in a batch query to avoid N+1 queries.
-
#all(type : T.class) : Array(T) forall T
Execute a query and return results of specified type This is used for method chaining with where, limit, offset, etc.
-
#all : Array(Target)
Returns all associated records - return : Array(Target)
-
#all?(&block : Target -> Bool)
Check if all records match the given block - param : block (Block(Target, Bool)) - return : Bool
-
#any?(&block : Target -> Bool)
Check if any record matches the given block - param : block (Block(Target, Bool)) - return : Bool
-
#build(**attributes)
Creates a new, unsaved record with the parent association set - param : attributes (NamedTuple | Hash(Symbol, DB::Any)) - return : Target
-
#clear
Clears all associated records from the parent record with the association's
dependent:strategy (:destroy,:delete_all, or:nullify, the default, which needs a nullable foreign key) - return : Int64 - Number of records affected -
#concat(records : Array(Target)) : Array(Target)
Add multiple records to the collection - param : records (Array(Target)) - return : Array(Target)
-
#count : Int64
Count records directly from database without loading - return : Int64
-
#create(record : Target)
Associates record with the parent: a new record is inserted without validations, a saved one (soft-deleted included) gets its foreign key updated with
save!. -
#create(**attributes)
Creates a new record with the given attributes and saves it - param : attributes (NamedTuple | Hash(Symbol, DB::Any)) - return : Target - raise : RelationError
-
#delete(record : Target)
Delete the associated record from the parent record if it exists - param : record (Target) - return : Bool
-
#delete(id : Pk)
Delete the associated record from the parent record if it exists - param : id (Pk) - return : Bool
-
#delete_all : Int64
Delete all associated records - return : Int64 - Number of records deleted
-
#each(&block : Target -> )
Implements the each method for the Enumerable module - param : block (Block(Target)) - return : Nil
-
#each_with_index(&block : Target, Int32 -> )
Each with index - param : block (Block(Target, Int32)) - return : Nil
-
#empty?
Checks if the collection is empty - return : Bool
-
#exists?(**attributes)
Checks if any records exist with the given attributes - param : attributes (NamedTuple) - return : Bool
-
#find(**attributes)
Find associated records matching the given attributes - param : attributes (NamedTuple | Hash(Symbol, DB::Any)) - return : Array(Target)
-
#find(&block : Target -> Bool)
Find the first record matching the given block - param : block (Block(Target, Bool)) - return : Target?
-
#find_by(**attributes)
Finds a single record by attributes - param : attributes (NamedTuple | Hash(Symbol, DB::Any)) - return : Target?
-
#first
Returns the first record in the collection, raises if none found - return : Target - raise : AssociationNotFound if no records exist
-
#first?
Returns the first record in the collection - return : Target?
-
#ids : Array(Pk)
Returns a list of primary keys for the associated records - return : Array(Pk)
-
#ids=(ids : Array(Pk))
Associates the parent record with the records that match the primary keys provided - param : ids (Array(Pk)) - return : Array(Target)
-
#includes?(record : Target) : Bool
Check if the collection includes a specific record - param : record (Target) - return : Bool
-
#last
Returns the last record in the collection, raises if none found - return : Target - raise : AssociationNotFound if no records exist
-
#last?
Returns the last record in the collection - return : Target?
-
#length
Get the length/size of the collection - return : Int32
-
#limit(limit_count : Int32)
Apply a limit to the query - param : limit_count (Int32) - return : CQL::Query
-
#loaded? : Bool
Check if the collection has been loaded - return : Bool
-
#map(&block : Target -> U) forall U
Map over the collection - param : block (Block(Target, U)) - return : Array(U)
-
#map_with_index(&block : Target, Int32 -> U) forall U
Map with index - param : block (Block(Target, Int32, U)) - return : Array(U)
-
#nullify_all : Int64
Set all foreign keys to nil (nullify association) - return : Int64 - Number of records updated
-
#offset(offset_count : Int32)
Apply an offset to the query - param : offset_count (Int32) - return : CQL::Query
-
#order(**order_by)
Order the query results, for example
user.posts.order(created_at: :desc)- param : order_by (column: direction) - each column with :asc or :desc - return : CQL::Query -
#reject(&block : Target -> Bool)
Reject records matching the given block - param : block (Block(Target, Bool)) - return : Array(Target)
-
#reload
Reloads the association records from the database - return : Array(Target)
-
#remove(records : Array(Target)) : Array(Target)
Remove records from the collection without deleting them - param : records (Array(Target)) - return : Array(Target)
-
#select(&block : Target -> Bool)
Select records matching the given block - param : block (Block(Target, Bool)) - return : Array(Target)
-
#size
Returns the number of associated records - return : Int32
-
#to_a
Convert to array - return : Array(Target)
-
#where(__sql sql : String, *positional, **named)
A raw SQL fragment with bound
?/:namevalues, scoped to this association. -
#where(**conditions)
Returns a new query for chaining where conditions - param : conditions (NamedTuple | Hash(Symbol, DB::Any)) - return : CQL::Query
Macros inherited from module CQL::ActiveRecord::Relations::BaseRelation
build_query(model_class)
build_query,
destroy_dependent(record, association)
destroy_dependent,
ensure_saved(record)
ensure_saved,
safe_db_operation(&block)
safe_db_operation,
safe_foreign_key(record, key, pk_type)
safe_foreign_key,
safe_id(record, pk_type)
safe_id,
underscore_name(class_name)
underscore_name
Constructor Detail
Initialize the collection class for a one-to-many relationship
- param : key (Symbol) - The foreign key in the target table (e.g., :user_id)
- param : id (Pk) - The id value for the parent record
- param : cascade (Bool) - Whether to delete associated records when parent is deleted (deprecated, use dependent)
- param : query (CQL::Query) - Base query; the collection scopes it to the parent and operations run on clones of it
- param : auto_load (Bool) - Whether to automatically load associated records
- param : dependent (Symbol) - Dependency handling strategy
- return : Collection(Target, Pk)
Example
CQL::ActiveRecord::Relations::Collection(Post, Int64).new(
:user_id,
1_i64,
query: CQL::Query.new(Post.schema).from(Post.table),
dependent: :destroy
)
Instance Method Detail
Adds a record to the collection, as #create(record) does.
- param : record (Target)
- return : Array(Target)
- raise : CQL::RecordInvalid when a saved record fails its validations
Example
user.posts << Post.new(title: "Hello World")
Get element at index, raises if out of bounds
- param : index (Int32)
- return : Target
Get element at index, returns nil if out of bounds
- param : index (Int32)
- return : Target?
Inject preloaded records without database query Used by eager loading/preload to set association data that was loaded in a batch query to avoid N+1 queries.
- param : records (Array(Target)) - The preloaded records
- return : Nil
Execute a query and return results of specified type This is used for method chaining with where, limit, offset, etc.
- param : type (Class) - The model type to return
- return : Array(T)
Example
user.posts.offset(2).all(Post)
Returns all associated records
- return : Array(Target)
Example
user.posts.all
Check if all records match the given block
- param : block (Block(Target, Bool))
- return : Bool
Check if any record matches the given block
- param : block (Block(Target, Bool))
- return : Bool
Creates a new, unsaved record with the parent association set
- param : attributes (NamedTuple | Hash(Symbol, DB::Any))
- return : Target
Example
post = user.posts.build(title: "New Post")
post.save! # => true
Clears all associated records from the parent record with the association's dependent:
strategy (:destroy, :delete_all, or :nullify, the default, which needs a nullable foreign key)
- return : Int64 - Number of records affected
Example
user.posts.create(title: "Hello World")
user.posts.clear
Add multiple records to the collection
- param : records (Array(Target))
- return : Array(Target)
Associates record with the parent: a new record is inserted without validations, a saved
one (soft-deleted included) gets its foreign key updated with save!.
- param : record (Target)
- return : Target
- raise : RelationError, or CQL::RecordInvalid when a saved record fails its validations
Creates a new record with the given attributes and saves it
- param : attributes (NamedTuple | Hash(Symbol, DB::Any))
- return : Target
- raise : RelationError
Example
user.posts.create(title: "Hello World")
Delete the associated record from the parent record if it exists
- param : record (Target)
- return : Bool
Example
post = user.posts.create(title: "Hello World")
user.posts.delete(post) # => true
Delete the associated record from the parent record if it exists
- param : id (Pk)
- return : Bool
Example
post = user.posts.create(title: "Hello World")
user.posts.delete(post.id!) # => true
Implements the each method for the Enumerable module
- param : block (Block(Target))
- return : Nil
Each with index
- param : block (Block(Target, Int32))
- return : Nil
Checks if any records exist with the given attributes
- param : attributes (NamedTuple)
- return : Bool
Find associated records matching the given attributes
- param : attributes (NamedTuple | Hash(Symbol, DB::Any))
- return : Array(Target)
Example
user.posts.find(title: "Hello World")
Find the first record matching the given block
- param : block (Block(Target, Bool))
- return : Target?
Finds a single record by attributes
- param : attributes (NamedTuple | Hash(Symbol, DB::Any))
- return : Target?
Returns the first record in the collection, raises if none found
- return : Target
- raise : AssociationNotFound if no records exist
Returns a list of primary keys for the associated records
- return : Array(Pk)
Example
user.posts.ids
Associates the parent record with the records that match the primary keys provided
- param : ids (Array(Pk))
- return : Array(Target)
Example
user.posts.ids = [1_i64, 2_i64, 3_i64]
Check if the collection includes a specific record
- param : record (Target)
- return : Bool
Returns the last record in the collection, raises if none found
- return : Target
- raise : AssociationNotFound if no records exist
Apply a limit to the query
- param : limit_count (Int32)
- return : CQL::Query
Map over the collection
- param : block (Block(Target, U))
- return : Array(U)
Map with index
- param : block (Block(Target, Int32, U))
- return : Array(U)
Set all foreign keys to nil (nullify association)
- return : Int64 - Number of records updated
Apply an offset to the query
- param : offset_count (Int32)
- return : CQL::Query
Order the query results, for example user.posts.order(created_at: :desc)
- param : order_by (column: direction) - each column with :asc or :desc
- return : CQL::Query
Reject records matching the given block
- param : block (Block(Target, Bool))
- return : Array(Target)
Reloads the association records from the database
- return : Array(Target)
Example
user.posts.reload
Remove records from the collection without deleting them
- param : records (Array(Target))
- return : Array(Target)
Select records matching the given block
- param : block (Block(Target, Bool))
- return : Array(Target)
A raw SQL fragment with bound ? / :name values, scoped to this association.
Returns a new query for chaining where conditions
- param : conditions (NamedTuple | Hash(Symbol, DB::Any))
- return : CQL::Query
Example
user.posts.where(title: "Hello").where(published: true).all(Post)