Relationships
CQL Active Record provides powerful association functionality that enables you to define and work with relationships between models. The relationship system supports lazy loading, eager loading, and provides a comprehensive API for creating, querying, and manipulating associated records.
Supported Association Types
CQL supports four main types of associations, each providing a rich set of methods for working with related data:
1. belongs_to
belongs_to
Defines a one-to-one association where the current model contains the foreign key. Used when a record belongs to another record.
Example: A Post belongs to a User
class Post
include CQL::ActiveRecord::Model(Int32)
property user_id : Int32?
belongs_to :user, User, :user_id, optional: true, cache: true
end
2. has_one
has_one
Defines a one-to-one association where the other model contains the foreign key. Used when a record has exactly one of another record.
Example: A User has one Profile
class User
include CQL::ActiveRecord::Model(Int32)
has_one :profile, UserProfile, foreign_key: :user_id, dependent: :destroy
end
3. has_many
has_many
Defines a one-to-many association where the other model contains the foreign key. Used when a record can have multiple associated records.
Example: A User has many Posts
class User
include CQL::ActiveRecord::Model(Int32)
has_many :posts, Post, foreign_key: :user_id, dependent: :destroy
end
4. many_to_many
many_to_many
Defines a many-to-many association using a join table. Used when records can have multiple associations on both sides.
Example: Movies and Actors (many-to-many)
class Movie
include CQL::ActiveRecord::Model(Int32)
many_to_many :actors, Actor, join_through: :movies_actor, dependent: :destroy
end
class Actor
include CQL::ActiveRecord::Model(Int32)
many_to_many :movies, Movie, join_through: :movies_actor
end
Association Features
Lazy Loading
Associations are loaded on-demand when first accessed, optimizing performance by only fetching data when needed.
Memoization
Once loaded, associations are cached for the lifetime of the object instance, preventing unnecessary database queries.
Collection Methods
has_many
and many_to_many
associations return collection objects that provide methods for:
Creating new associated records
Finding records by attributes
Checking existence
Counting records
Clearing associations
Reloading data
Dependent Options
Control what happens to associated records when the parent is destroyed:
:destroy
- Destroy associated records:delete
- Delete associated records without callbacksnil
- Leave associated records orphaned (default)
Optional Associations
Mark associations as optional when the foreign key can be nil:
belongs_to :user, User, :user_id, optional: true
Caching
Enable association caching to improve performance:
belongs_to :user, User, :user_id, cache: true
Association API Methods
For belongs_to
associations:
belongs_to
associations:record.association
- Get the associated recordrecord.association=
- Set the associated recordrecord.build_association
- Build a new associated recordrecord.create_association
- Create and save a new associated recordrecord.update_association
- Update the associated recordrecord.delete_association
- Remove the association (set foreign key to nil)
For has_one
associations:
has_one
associations:record.association
- Get the associated recordrecord.association=
- Set the associated recordrecord.build_association
- Build a new associated recordrecord.create_association
- Create and save a new associated recordrecord.update_association
- Update the associated recordrecord.delete_association
- Delete the associated record
For has_many
and many_to_many
associations:
has_many
and many_to_many
associations:record.associations
- Get the association collectionrecord.associations.create
- Create a new associated recordrecord.associations.find
- Find records by attributesrecord.associations.exists?
- Check if records existrecord.associations.size
- Count associated recordsrecord.associations.clear
- Remove all associationsrecord.associations.delete
- Remove specific recordsrecord.associations.reload
- Reload the collection from databaserecord.associations.ids
- Get array of associated record IDsrecord.associations.ids=
- Set associations by IDsrecord.reload_associations
- Reload and get new collection instance
Relationship Guides
Detailed guides for each association type with complete examples:
Belongs To: One-to-one relationships where this model has the foreign key
Has One: One-to-one relationships where the other model has the foreign key
Has Many: One-to-many relationships for collections of associated records
Many To Many: Many-to-many relationships using join tables
Each guide includes:
Schema and Model Setup: How to define tables and relationships
Basic Usage: Creating and accessing associations
Advanced Features: Using collection methods, dependent options, and performance optimizations
Complete Examples: Real-world scenarios with full code samples
Best Practices
Performance
Use
cache: true
for frequently accessedbelongs_to
associationsConsider eager loading for scenarios where you'll access multiple associations
Use
dependent: :destroy
or:delete
to maintain referential integrity
Schema Design
Follow naming conventions (singular for
belongs_to
/has_one
, plural forhas_many
/many_to_many
)Use appropriate foreign key column names (e.g.,
user_id
for a User association)Create proper database indexes on foreign key columns
Code Organization
Define associations after properties but before validations
Group related associations together
Use descriptive association names that reflect the business relationship
The CQL association system provides a powerful, type-safe way to work with related data while maintaining excellent performance through lazy loading and intelligent caching.
Last updated
Was this helpful?