Ruby logoRubyv8.1INTERMEDIATE

Ruby on Rails

Ruby on Rails cheat sheet with MVC architecture, Active Record, routing, migrations, controllers, and deployment code examples.

8 min read
railsrubymvcactive-recordbackendweb-frameworkgeneratorsmigrations

Sign in to mark items as known and track your progress.

Sign in

Getting Started

New Rails Application

Create a new Rails application with various options

bash
# Basic app
rails new myapp

# API-only app
rails new myapp --api

# Skip specific components
rails new myapp --skip-test --skip-bundle
✅ Default database is SQLite, use --database for PostgreSQL/MySQL
💡 --api flag creates lightweight API-only app
🔍 --skip-test useful if using RSpec instead of Minitest
⚡ Use rails new --help to see all available options
setupclinew-app

Rails Server & Console

Start development server and interactive console

bash
# Start development server
rails server
# or shorthand
rails s

# Specify port
rails s -p 3001

# Rails console
rails console
rails c
✅ Default server runs on localhost:3000
💡 Use rails c --sandbox to test without affecting database
🔍 reload! in console reloads code without restarting
⚡ rails server accepts same flags as rails s
serverconsoledevelopment

Generators

Model Generator

Generate models with migrations and attributes

bash
# Basic model
rails generate model User name:string email:string

# Model with references
rails generate model Post title:string body:text user:references

# Model with indexes
rails generate model Product name:string:index price:decimal
✅ Automatically creates migration, model, and test files
💡 Use references for associations (creates foreign key)
🔍 :index adds database index, :uniq adds unique index
⚡ rails destroy model reverses the generator
generatormodelmigration

Controller Generator

Generate controllers with actions and views

bash
# Controller with actions
rails generate controller Users index show new create

# API controller
rails generate controller api/v1/Posts index show --skip-template-engine

# Empty controller
rails generate controller Admin
✅ Creates controller, views, helper, and routes
💡 --skip-template-engine for API-only controllers
🔍 Namespaced controllers use slashes: api/v1/Users
⚡ Actions listed after controller name become methods
generatorcontrollercrud

Scaffold Generator

Generate complete CRUD resource with all components

bash
# Full scaffold
rails generate scaffold Post title:string body:text published:boolean

# API scaffold
rails generate scaffold_controller api/v1/Article \
  title:string body:text \
  --api
✅ Creates model, migration, controller, views, routes, tests
💡 Great for prototyping, customize afterwards
🔍 --api flag creates API-only scaffold without views
⚠️ Generates a lot of files - review before committing
generatorscaffoldcrudfull-stack

Migration Generator

Generate standalone database migrations

bash
# Add column migration
rails generate migration AddEmailToUsers email:string

# Remove column migration
rails generate migration RemoveEmailFromUsers email:string

# Create join table
rails generate migration CreateJoinTableUserProject user project
✅ Rails infers migration content from name convention
💡 AddXxxToYyy and RemoveXxxFromYyy auto-generate code
🔍 Use CreateJoinTable for many-to-many relationships
⚡ Always review generated migration before running
generatormigrationdatabase

Database & Migrations

Database Commands

Create, migrate, and manage database

bash
# Create database
rails db:create

# Run migrations
rails db:migrate

# Rollback last migration
rails db:rollback

# Drop database
rails db:drop
✅ db:create creates database defined in database.yml
💡 db:reset drops and recreates from schema.rb
🔍 db:setup is for first-time setup, db:reset for refresh
⚡ Always backup production before db:reset or db:drop
databasemigrationssetup

Migration Methods

Common methods used in migration files

ruby
class CreateProducts < ActiveRecord::Migration[7.0]
  def change
    create_table :products do |t|
      t.string :name
      t.text :description
      t.decimal :price, precision: 8, scale: 2
      t.integer :stock, default: 0
      t.references :category, foreign_key: true

      t.timestamps
    end

    add_index :products, :name
  end
end
✅ t.timestamps adds created_at and updated_at
💡 Use references for foreign keys with index
🔍 precision and scale control decimal places
⚡ Add indexes for frequently queried columns
migrationsschemadatabase

Routes

Resourceful Routes

RESTful routes with resources

ruby
# Full CRUD routes
resources :posts

# Limit to specific actions
resources :posts, only: [:index, :show]
resources :posts, except: [:destroy]

# Nested resources
resources :users do
  resources :posts
end
✅ resources generates 7 RESTful routes automatically
💡 Use only/except to limit generated routes
🔍 Shallow nesting prevents deep URL structures
⚡ Check routes with rails routes command
routesrestresources

Custom Routes

Define custom routes and root

ruby
# Root route
root 'posts#index'

# Simple route
get 'about', to: 'pages#about'

# Route with dynamic segments
get 'posts/:id', to: 'posts#show'

# Named routes
get 'dashboard', to: 'dashboard#index', as: :user_dashboard
✅ root route defines homepage (must be first)
💡 Use as: option to create custom path helper
🔍 Constraints validate route parameters
⚡ rails routes | grep posts to filter routes
routescustomhttp

Controllers

Controller Actions

Common controller patterns and responses

ruby
class PostsController < ApplicationController
  def index
    @posts = Post.all
    render json: @posts
  end

  def show
    @post = Post.find(params[:id])
    render :show
  end

  def create
    @post = Post.new(post_params)
    if @post.save
      redirect_to @post, notice: 'Created!'
    else
      render :new, status: :unprocessable_entity
    end
  end
end
✅ Use before_action for common setup code
💡 Strong parameters required for mass assignment
🔍 respond_to handles multiple formats
⚡ Use includes() to avoid N+1 queries
controllersactionscrud

Filters & Callbacks

Before/after/around filters for controller actions

ruby
class ApplicationController < ActionController::Base
  before_action :authenticate_user!
  before_action :set_locale
  after_action :log_action
  around_action :catch_errors

  private

  def set_locale
    I18n.locale = params[:locale] || I18n.default_locale
  end
end
✅ before_action runs before controller actions
💡 Use only/except to limit filter scope
🔍 skip_before_action skips inherited filters
⚡ around_action wraps action execution
controllersfilterscallbacks

Models & Active Record

Model Associations

Define relationships between models

ruby
class User < ApplicationRecord
  has_many :posts
  has_one :profile
end

class Post < ApplicationRecord
  belongs_to :user
  has_many :comments
end

class Comment < ApplicationRecord
  belongs_to :post
end
✅ belongs_to creates foreign key relationship
💡 dependent: :destroy deletes associated records
🔍 has_many :through for many-to-many relationships
⚡ Use counter_cache to avoid COUNT queries
modelsassociationsrelationships

Validations

Validate model data before saving

ruby
class User < ApplicationRecord
  validates :email, presence: true, uniqueness: true
  validates :name, presence: true, length: { minimum: 2 }
  validates :age, numericality: { greater_than: 18 }
end
✅ Validations run before save/create/update
💡 Use presence: true for required fields
🔍 Custom validations via validate method
⚡ Conditional validations with if/unless
modelsvalidationsdata-integrity

Queries & Scopes

Query database with Active Record

ruby
# Find records
Post.find(1)
Post.find_by(title: 'Hello')
Post.where(published: true)
Post.all

# Chain queries
Post.where(published: true).order(created_at: :desc).limit(10)
✅ Use find_by instead of where().first
💡 includes() prevents N+1 query problems
🔍 Scopes make queries reusable and chainable
⚡ Use select() to fetch only needed columns
modelsqueriesactive-recordscopes

Callbacks

Lifecycle hooks for model operations

ruby
class Post < ApplicationRecord
  before_validation :normalize_title
  before_save :generate_slug
  after_create :send_notification
  after_destroy :cleanup_files

  private

  def normalize_title
    self.title = title.strip.titleize
  end
end
✅ Callbacks run automatically during object lifecycle
💡 before_validation runs before validations
🔍 Use conditional callbacks with if/unless
⚠️ Avoid complex logic in callbacks, use service objects
modelscallbackslifecycle