Skip to content

Ror Activerecord

DodaTech 3 min read

title: Ruby on Rails Active Record — Complete Guide to the ORM description: 'Learn Ruby on Rails Active Record: ORM mapping, CRUD operations, query interface, eager loading, SQL methods, migrations, and advanced querying techniques.' date: 2026-06-28 lastmod: 2026-06-28 weight: 18 tags: [backend, ror]


Active Record is Rails' object-relational mapping layer that connects Ruby classes to database tables, providing CRUD operations, query building, and relationship management.

## What You'll Learn

By the end of this tutorial, you'll perform CRUD operations, build complex queries with the query interface, eager load associations, use raw SQL when needed, and understand the Active Record pattern.

## Real-World Use

An analytics dashboard queries millions of records with Active Record's query interface, using select, group, having, and calculations to generate reports without raw SQL.

## Active Record Learning Path

```mermaid
flowchart LR
  A[Models] --> B[Active Record]
  B --> C[Migrations]
  C --> D[Validations]
  D --> E[Associations]
  B --> F{You Are Here}
  style F fill:#f90,color:#fff

CRUD Operations

# Create
user = User.new(name: "Alice", email: "alice@example.com")
user.save
User.create(name: "Bob", email: "bob@example.com")

# Read
User.find(1)
User.find_by(email: "alice@example.com")
User.where(active: true).order(name: :asc)
User.limit(10).offset(20)

# Update
user = User.find(1)
user.update(name: "Alice Updated")
User.where(active: true).update_all(status: "notified")

# Delete
user.destroy
User.destroy_by(active: false)
User.where("created_at < ?", 1.year.ago).delete_all

Query Interface

# Conditions
User.where(name: "Alice")
User.where("name LIKE ?", "%Ali%")
User.where(name: ["Alice", "Bob"])
User.where.not(active: false)

# Ordering
Post.order(created_at: :desc)
Post.order(published_at: :desc, title: :asc)

# Selecting specific columns
User.select(:id, :name, :email)

# Joins
Post.joins(:comments)
Post.joins("INNER JOIN users ON users.id = posts.user_id")
Post.left_joins(:comments).where(comments: { id: nil })

# Group and Having
Post.group(:status).count
Post.group(:status).having("count(*) > 10")

# Calculations
Post.count
Post.sum(:views_count)
Post.average(:rating)
Post.minimum(:price)
Post.maximum(:price)

Eager Loading

# N+1 problem (BAD)
@posts = Post.limit(10)
@posts.each { |post| puts post.user.name }  # 11 queries

# Eager loading with includes (GOOD)
@posts = Post.includes(:user).limit(10)
@posts.each { |post| puts post.user.name }  # 2 queries

# Nested eager loading
Post.includes(user: [:profile, :settings])
Post.includes(:comments, :user)

# Preload vs Eager Load vs Joins
Post.preload(:comments)     # Always separate query
Post.eager_load(:comments)  # LEFT JOIN
Post.joins(:comments)       # INNER JOIN (no association loaded)

Raw SQL

# find_by_sql
Post.find_by_sql("SELECT * FROM posts WHERE published = true")

# count_by_sql
count = ActiveRecord::Base.connection.execute("SELECT count(*) FROM posts")

# Arel for complex queries
posts = Post.arel_table
query = posts.where(posts[:created_at].gteq(1.week.ago))
            .order(posts[:views_count].desc)
            .limit(10)
Post.find_by_sql(query.to_sql)

Common Mistakes

1. N+1 Queries

The most common performance issue. Use includes(:association) to eager load.

2. Loading Too Much Data

Fetching thousands of records without pagination. Use limit/offset or pagination gems (kaminari, will_paginate).

3. Not Using Database Indexes

Queries on unindexed columns are slow for large tables. Add indexes in migrations.

4. Overusing Ruby Enumerables

Post.all.select { |p| p.published? } loads all records. Use Post.where(published: true) for database filtering.

5. Ignoring SQL in Logs

Development logs show every query. Watch for N+1, missing indexes, and unexpected queries.

Practice Questions

1. What is the Active Record pattern?

Each database table maps to a Ruby class, each row maps to an object instance, and columns map to object attributes.

2. How do you prevent N+1 queries?

Use includes(:association) to eager load related records in a single query.

3. What is the difference between joins and includes?

joins performs INNER JOIN (no association loaded). includes loads associated records (avoids N+1).

4. How do you execute raw SQL in Active Record?

Use find_by_sql for selecting, or ActiveRecord::Base.connection.execute for any SQL.

5. Challenge: Write a query that returns top 10 users with the most posts, including post counts.

User.joins(:posts)
    .group(:id)
    .select("users.*, count(posts.id) as post_count")
    .order("post_count DESC")
    .limit(10)

FAQ

Is Active Record suitable for complex queries?

Yes for 95% of cases. For very complex queries, use find_by_sql, Arel, or database views.

What is the difference between update and update!

update returns false on validation failure. update! raises ActiveRecord::RecordInvalid.

How do I use transactions?

ActiveRecord::Base.transaction do ... end. All operations succeed or roll back together.

What are counter caches?

belongs_to :user, counter_cache: true maintains a posts_count column on users, avoiding count queries.

How do I use enums in Active Record?

enum status: { draft: 0, published: 1 }. Adds status.draft?, status.published!, status.published? predicate methods.

Mini Project: Advanced Queries

Practice complex Active Record queries with joins, grouping, and eager loading.

# Users with post counts
User.left_joins(:posts)
    .group(:id)
    .select("users.*, COUNT(posts.id) as post_count")

# Recent popular posts
Post.published.includes(:user)
    .where("views_count > 100")
    .order(created_at: :desc)
    .limit(20)

What's Next

Ruby on Rails Migrations Ruby on Rails Validations

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro