Has Many

CQL Active Record: HasMany Relationship Guide

In this guide, we'll focus on the HasMany relationship using CQL's Active Record syntax. This describes a one-to-many connection between models.

What is a HasMany Relationship?

The HasMany relationship indicates that one entity (a record) is related to multiple other entities. For example, a Post can have many Comments. This relationship is a one-to-many mapping between two entities.

Example Scenario: Posts and Comments

In a blogging system:

  • A Post can have many Comments.

  • Each Comment belongs to one Post.

This is a common one-to-many relationship where one post can have multiple comments, but each comment refers to only one post.


Defining the Schema

We'll define the posts and comments tables in the schema using CQL's DSL.

AcmeDB = CQL::Schema.define(
  :acme_db,
  adapter: CQL::Adapter::Postgres,
  uri: ENV["DATABASE_URL"]
) do
  table :posts do
    primary :id, Int64, auto_increment: true
    text :title
    text :body
    timestamp :published_at
  end

  table :comments do
    primary :id, Int64, auto_increment: true
    bigint :post_id
    text :body
  end
end
  • posts table: Stores post details like title, body, and published_at.

  • comments table: Stores comment details with a foreign key post_id that references the posts table.


Defining the Models

Let's db_context the Post and Comment models and establish the HasMany and BelongsTo relationships in CQL.

Post Model

  • The has_many :comments, Comment, foreign_key: :post_id association in the Post model defines that each post can have multiple comments. The comments table must have a post_id column.

Comment Model

  • The belongs_to :post, Post, :post_id in the Comment model links each comment back to its post.

Working with the HasMany Collection

When you access a has_many association (e.g., post.comments), you get a collection proxy object that offers several methods to query and manipulate the associated records.

Creating and Adding Records

Retrieving Records from the Collection

The collection is enumerable and provides methods to access its records.

Reloading the Collection

If the database might have changed, reload the collection:

The has_many macro generates reload_{{association_name}} (e.g., reload_comments).

Removing and Deleting Records

Deleting a specific comment from the association (and database):

Note: The delete method on the collection typically removes the record from the database.

Clearing the association (deletes all associated comments):

  • clear usually implies deleting the associated records from the database. Be cautious with this method.

If you delete the parent record (post.delete), associated comments are not automatically deleted unless cascade: true was specified in the has_many definition or database-level cascade rules are in place.


Eager Loading

To avoid N+1 query problems when loading many posts and their comments, use joins:

  • join(:comments) tells CQL to fetch all comments for the retrieved posts using efficient JOIN operations.


Summary

In this guide, we've explored the HasMany relationship in CQL. We covered:

  • Defining Post and Comment models with has_many and belongs_to associations, including the foreign_key option.

  • Interacting with the has_many collection using methods like create, build, <<, all, find_by, exists?, size, delete, and clear.

  • Eager loading associations with includes.

Next Steps

In the next guide, we'll build upon this ERD and cover the ManyToMany relationship.

Last updated

Was this helpful?