Active Record Basics
Active Record is Rails' ORM (Object-Relational Mapping) that connects your Ruby objects to database tables. It makes database operations feel like working with plain Ruby objects.
What is Active Record?
Active Record follows the Active Record pattern where:
- Each database table maps to a Ruby class
- Each row in the table maps to an object of that class
- Each column maps to an attribute of that object
ruby
1# Table: users
2# | id | name | email | created_at |
3# |----|-------|-----------------|------------|
4# | 1 | John | john@email.com | 2024-01-15 |
5# | 2 | Jane | jane@email.com | 2024-01-16 |
6
7# Ruby class
8class User < ApplicationRecord
9end
10
11# Object
12user = User.find(1)
13user.name # => "John"
14user.email # => "john@email.com"Creating a Model
Using the Generator
bash
1rails generate model User name:string email:string age:integer active:boolean
2
3# Creates:
4# app/models/user.rb
5# db/migrate/xxx_create_users.rb
6# test/models/user_test.rbThe Model File
ruby
1# app/models/user.rb
2class User < ApplicationRecord
3 # Model code goes here
4endThe Migration File
ruby
1# db/migrate/20240115000000_create_users.rb
2class CreateUsers < ActiveRecord::Migration[7.1]
3 def change
4 create_table :users do |t|
5 t.string :name
6 t.string :email
7 t.integer :age
8 t.boolean :active, default: true
9
10 t.timestamps # Adds created_at and updated_at
11 end
12 end
13endNaming Conventions
Rails uses naming conventions to connect models to tables:
| Model (Singular) | Table (Plural) |
|---|---|
| User | users |
| Article | articles |
| Person | people |
| LineItem | line_items |
Override with:
ruby
1class User < ApplicationRecord
2 self.table_name = "my_users"
3 self.primary_key = "user_id"
4endCRUD Operations
Create
ruby
1# Method 1: new + save
2user = User.new
3user.name = "John"
4user.email = "john@example.com"
5user.save # Returns true/false
6
7# Method 2: new with hash
8user = User.new(name: "John", email: "john@example.com")
9user.save
10
11# Method 3: create (new + save in one step)
12user = User.create(name: "John", email: "john@example.com")
13
14# Method 4: create! (raises exception on failure)
15user = User.create!(name: "John", email: "john@example.com")Read
ruby
1# Find by ID
2user = User.find(1) # Raises error if not found
3user = User.find_by(id: 1) # Returns nil if not found
4
5# Find by attribute
6user = User.find_by(email: "john@example.com")
7user = User.find_by!(email: "john@example.com") # Raises if not found
8
9# Find all
10users = User.all
11
12# Find with conditions
13users = User.where(active: true)
14users = User.where("age > ?", 18)
15users = User.where("name LIKE ?", "%John%")
16
17# First and last
18first_user = User.first
19last_user = User.last
20
21# Count
22User.count
23User.where(active: true).countUpdate
ruby
1# Method 1: Find, modify, save
2user = User.find(1)
3user.name = "Jane"
4user.save
5
6# Method 2: update
7user = User.find(1)
8user.update(name: "Jane")
9
10# Method 3: update! (raises on failure)
11user.update!(name: "Jane")
12
13# Update all matching records
14User.where(active: false).update_all(active: true)
15
16# Update single attribute (skips validations)
17user.update_attribute(:name, "Jane")
18
19# Update column directly (skips callbacks and validations)
20user.update_column(:name, "Jane")Delete
ruby
1# Delete a single record (runs callbacks)
2user = User.find(1)
3user.destroy
4
5# Delete by ID
6User.destroy(1)
7
8# Delete all matching
9User.where(active: false).destroy_all
10
11# Delete without callbacks
12user.delete
13User.delete(1)
14User.where(active: false).delete_allWorking with Records
Checking State
ruby
1user = User.new
2
3user.new_record? # => true (not saved yet)
4user.persisted? # => false
5
6user.save
7
8user.new_record? # => false
9user.persisted? # => true
10
11user.changed? # => false
12user.name = "New Name"
13user.changed? # => true
14user.name_changed? # => true
15user.changes # => {"name"=>["John", "New Name"]}
16
17# Check if record exists
18User.exists?(1)
19User.exists?(email: "john@example.com")
20User.where(active: true).exists?Reloading
ruby
1user = User.find(1)
2# Someone else updates the record in the database
3user.reload # Refresh from databaseAttributes
ruby
1user = User.find(1)
2
3# Get all attributes as a hash
4user.attributes
5# => {"id"=>1, "name"=>"John", "email"=>"john@example.com", ...}
6
7# Access attributes
8user[:name]
9user.name
10user.read_attribute(:name)
11
12# Set attributes
13user[:name] = "Jane"
14user.name = "Jane"
15user.write_attribute(:name, "Jane")
16
17# Assign multiple (doesn't save)
18user.assign_attributes(name: "Jane", email: "jane@example.com")
19user.saveDate and Time Columns
ruby
1# timestamps are automatically added
2class CreatePosts < ActiveRecord::Migration[7.1]
3 def change
4 create_table :posts do |t|
5 t.string :title
6 t.datetime :published_at
7 t.date :event_date
8 t.time :start_time
9
10 t.timestamps # created_at and updated_at
11 end
12 end
13end
14
15# Using date/time
16post = Post.create(
17 title: "My Post",
18 published_at: Time.current,
19 event_date: Date.today,
20 start_time: Time.current
21)
22
23post.created_at # When created
24post.updated_at # When last updated (auto-updated)Touch
Update the updated_at timestamp:
ruby
1user.touch # Update updated_at to now
2user.touch(:last_login_at) # Update specific timestamp columnIncrement and Decrement
ruby
1# Increment counter
2article.increment(:views_count)
3article.increment!(:views_count) # Saves immediately
4
5# Decrement
6product.decrement(:stock)
7product.decrement!(:stock)Active Record makes database operations intuitive and Ruby-like!
