Ruby on Rails is a web framework that follows convention over configuration — it makes decisions for you so you can focus on building features instead of boilerplate.
Creating a New App
gem install rails
rails new myapp --database=sqlite3
cd myapp
rails serverVisit http://localhost:3000 to see your app running.
MVC Structure
Rails organises code into three layers:
| Layer | Folder | Responsibility |
|---|---|---|
| Model | app/models/ |
Data and business logic |
| View | app/views/ |
HTML templates |
| Controller | app/controllers/ |
Handles requests and responses |
Routes
Define URL patterns in config/routes.rb.
Rails.application.routes.draw do
root "pages#home"
get "/about", to: "pages#about"
post "/contact", to: "contact#create"
endresources generates all seven standard RESTful routes at once:
resources :articles
# GET /articles → articles#index
# GET /articles/:id → articles#show
# GET /articles/new → articles#new
# POST /articles → articles#create
# GET /articles/:id/edit → articles#edit
# PATCH /articles/:id → articles#update
# DELETE /articles/:id → articles#destroyCheck all routes with rails routes in the terminal.
Controllers
Generate a controller with its actions:
rails generate controller Articles index show newA controller action reads data and picks a view to render:
class ArticlesController < ApplicationController
def index
@articles = Article.all
end
def show
@article = Article.find(params[:id])
end
endInstance variables (starting with @) are automatically available in the view.
Use strong parameters to whitelist what users can submit:
def article_params
params.require(:article).permit(:title, :body)
endViews (ERB)
Views are HTML files with embedded Ruby, stored in app/views/<controller>/.
<!-- app/views/articles/index.html.erb -->
<h1>All Articles</h1>
<% @articles.each do |article| %>
<p><%= article.title %></p>
<% end %><% %> runs Ruby without printing anything. <%= %> runs Ruby and prints the result.
Common view helpers:
<%= link_to "Home", root_path %>
<%= link_to "Edit", edit_article_path(@article) %>
<%= link_to "Delete", @article, data: { turbo_method: :delete } %>
<%= image_tag "logo.png", alt: "Logo" %>Models
Generate a model with its database columns:
rails generate model Article title:string body:text published:booleanA model class inherits from ApplicationRecord and maps to a database table:
class Article < ApplicationRecord
# columns: id, title, body, published, created_at, updated_at
endMigrations
Migrations describe changes to the database schema. Run them with:
rails db:migrateA generated migration looks like this:
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 # adds created_at and updated_at
end
end
endActiveRecord — Creating and Saving
# Create and save in one step
article = Article.create(title: "Hello", body: "My first post")
# Build then save separately
article = Article.new(title: "Hello", body: "My first post")
article.save # => true
# Update a record
article.update(title: "Updated title")
# Delete a record
article.destroyActiveRecord — Querying
Article.all # => all articles
Article.find(1) # => article with id 1
Article.find_by(title: "Hello") # => first match or nil
Article.where(published: true) # => all published articles
Article.where("created_at > ?", 1.week.ago)
Article.order(created_at: :desc) # => newest first
Article.limit(10) # => first 10 records
Article.count # => 42Chain methods together:
Article.where(published: true).order(created_at: :desc).limit(5)Associations
Declare relationships between models:
class Author < ApplicationRecord
has_many :articles, dependent: :destroy
end
class Article < ApplicationRecord
belongs_to :author
has_many :comments
has_one :thumbnail
endUse associations like methods:
author = Author.find(1)
author.articles # => all articles by this author
author.articles.create(title: "New post")
article = Article.find(1)
article.author # => the author object
article.author.name # => "Alice"Validations
Add validations to your model to prevent bad data from being saved:
class Article < ApplicationRecord
validates :title, presence: true, length: { minimum: 3 }
validates :body, presence: true
validates :status, inclusion: { in: %w[draft published] }
endCheck if a record is valid:
article = Article.new(title: "")
article.valid? # => false
article.errors.full_messages
# => ["Title can't be blank", "Body can't be blank"]Rails Console
The Rails console lets you interact with your app from the terminal:
rails console # or: rails c# Try things out interactively
Article.count # => 3
Article.last.title # => "Hello World"
Article.create(title: "Test", body: "Body text")Useful Commands
rails generate model Post title:string # create a model
rails generate controller Pages home # create a controller
rails db:migrate # run pending migrations
rails db:rollback # undo the last migration
rails db:seed # run db/seeds.rb
rails routes # list all routes
rails test # run the test suite