ActiveRecord Basics

· 5 min read · Updated March 8, 2026 · beginner
activerecord rails models database crud

ActiveRecord is the ORM (Object-Relational Mapping) layer that comes with Ruby on Rails. It lets you interact with your database like you would with Ruby objects — no need to write raw SQL for most operations. In this tutorial, you’ll learn how to create models, perform CRUD operations, define relationships, and build queries with ActiveRecord.

What is ActiveRecord?

ActiveRecord is Rails’ implementation of the ORM pattern. It maps database tables to Ruby classes, and rows to objects. When you create a model in Rails, you get a powerful interface for interacting with your database.

# This automatically maps to a "users" table
class User < ApplicationRecord
end

Each attribute in the database becomes a method on your model:

user = User.find(1)
user.name   # => "Alice"
user.email  # => "alice@example.com"

Creating Models

Generate a model with the Rails generator:

rails generate model Article title:string body:text published:boolean

This creates:

  • app/models/article.rb — The model class
  • db/migrate/20260307123456_create_articles.rb — The migration

The model inherits from ApplicationRecord, which inherits from ActiveRecord::Base:

# app/models/article.rb
class Article < ApplicationRecord
end

CRUD Operations

ActiveRecord provides methods for all standard database operations:

Create

# Create a new article
article = Article.new(title: "Hello World", body: "My first post")
article.save

# Or use create to save in one step
article = Article.create(title: "Second Post", body: "Content here")

Read

# Find by primary key
article = Article.find(1)

# Find first match
article = Article.find_by(title: "Hello World")

# Get all records
articles = Article.all

# Find with conditions
published_articles = Article.where(published: true)

Update

article = Article.find(1)
article.title = "Updated Title"
article.save

# Or update in one step
article.update(title: "New Title", body: "New content")

# Update multiple records
Article.where(published: false).update_all(published: true)

Delete

article = Article.find(1)
article.destroy

# Delete without loading into memory
Article.destroy(1)
Article.destroy_all(published: true)

Validations

ActiveRecord lets you validate data before saving to the database:

class Article < ApplicationRecord
  validates :title, presence: true
  validates :body, length: { minimum: 10 }
  validates :slug, uniqueness: true
end

Common validations:

class User < ApplicationRecord
  validates :email, presence: true
  validates :email, format: { with: /\A[^@]+@[^@]+\z/ }
  validates :age, numericality: { greater_than: 0 }
  validates :username, length: { in: 3..20 }
  validates :terms, acceptance: true
end

Relationships

ActiveRecord makes defining database relationships simple:

Belongs To

class Article < ApplicationRecord
  belongs_to :author
end

Has Many

class Author < ApplicationRecord
  has_many :articles
end

Has One

class Profile < ApplicationRecord
  belongs_to :user
  has_one :avatar
end

Many-to-Many with Join Table

class Article < ApplicationRecord
  has_many :taggings
  has_many :tags, through: :taggings
end

class Tagging < ApplicationRecord
  belongs_to :article
  belongs_to :tag
end

class Tag < ApplicationRecord
  has_many :taggings
  has_many :articles, through: :taggings
end

Query Interface

ActiveRecord provides a powerful chainable query interface:

# Chaining scopes
articles = Article
  .where(published: true)
  .where("created_at > ?", 1.week.ago)
  .order(created_at: :desc)
  .limit(10)

Common methods:

# Filtering
Article.where(published: true)        # WHERE clause
Article.order(:title)                  # ORDER BY
Article.limit(5)                       # LIMIT
Article.offset(10)                     # OFFSET
Article.select(:title, :body)          # SELECT specific columns
Article.distinct                       # SELECT DISTINCT

# Aggregation
Article.count                          # COUNT
Article.sum(:view_count)               # SUM
Article.average(:rating)               # AVG
Article.minimum(:price)                # MIN
Article.maximum(:price)                # MAX

Scopes

Scopes are reusable query chains defined in your model:

class Article < ApplicationRecord
  # Simple scope
  scope :published, -> { where(published: true) }
  
  # Scope with arguments
  scope :recent, ->(days) { where("created_at > ?", days.days.ago) }
  
  # You can also define as class methods
  def self.popular
    where("view_count > ?", 1000)
  end
end

# Usage
Article.published.recent(7)
Article.popular.where(title: "Hello")

Callbacks

Callbacks let you run code at specific points in the object lifecycle:

class Article < ApplicationRecord
  before_validation :set_slug
  
  private
  
  def set_slug
    self.slug = title.parameterize if slug.blank?
  end
end

Common callbacks:

  • before_validation / after_validation
  • before_save / around_save / after_save
  • before_create / around_create / after_create
  • before_update / around_update / after_update
  • before_destroy / around_destroy / after_destroy

Migrations

Migrations manage your database schema over time:

# Create a migration
rails generate migration AddPublishedAtToArticles published_at:datetime

# Run migrations
rails db:migrate

# Rollback
rails db:rollback

Common migration operations:

class CreateArticles < ActiveRecord::Migration[7.1]
  def change
    create_table :articles do |t|
      t.string :title
      t.text :body
      t.boolean :published, default: false
      t.timestamps
    end
  end
end

Example: Complete Article Model

Here’s a more complete example bringing together what you’ve learned:

class Article < ApplicationRecord
  # Relationships
  belongs_to :author
  has_many :comments, dependent: :destroy
  has_many :taggings, dependent: :destroy
  has_many :tags, through: :taggings
  
  # Validations
  validates :title, presence: true, length: { minimum: 5 }
  validates :body, presence: true
  validates :slug, uniqueness: true
  
  # Scopes
  scope :published, -> { where(published: true) }
  scope :drafts, -> { where(published: false) }
  scope :recent, -> { order(created_at: :desc) }
  
  # Callbacks
  before_validation :generate_slug
  
  private
  
  def generate_slug
    self.slug = title.parameterize if slug.blank?
  end
end

Common Pitfalls

Watch out for these common issues:

# BAD: N+1 query problem
articles = Article.all
articles.each do |article|
  puts article.author.name  # Each access triggers a query!
end

# GOOD: Eager loading
articles = Article.includes(:author).all
articles.each do |article|
  puts article.author.name  # Authors loaded in one query
end
# BAD: Using update_column (bypasses validations)
article.update_column(:published, true)

# GOOD: Use update (runs validations)
article.update(published: true)

Summary

ActiveRecord is the heart of data handling in Rails:

  • Models map to database tables
  • CRUD operations are simple method calls
  • Validations ensure data integrity
  • Relationships connect models elegantly
  • Query Interface builds SQL chains in Ruby
  • Scopes create reusable queries
  • Callbacks hook into the object lifecycle

Master ActiveRecord and you’ll be able to build data-driven Rails applications efficiently without touching raw SQL.

In the next tutorial, we’ll explore Rails routing and see how HTTP requests are mapped to controller actions.