Ruby on Rails Tutorial for Beginners
By RubyLearning
Ruby on Rails is one of the most productive web frameworks ever created. This step-by-step ruby on rails tutorial walks you through everything from installation to building your first CRUD application, giving you the foundation you need to learn ruby on rails and start building real web applications.
Prerequisites
Before you begin this rails tutorial for beginners, make sure you have a basic understanding of the following:
- Ruby basics: Variables, methods, classes, blocks, and hashes. If you are new to Ruby, start with our free Ruby tutorial first.
- HTML and CSS: You should be comfortable writing basic HTML markup and styling with CSS.
- Command line familiarity: You will use the terminal throughout this tutorial to run generators, start servers, and manage your project.
- A text editor or IDE: VS Code, RubyMine, Sublime Text, or any editor you prefer.
Installing Ruby and Rails
To get started with this ruby on rails tutorial, you need Ruby and the Rails gem installed on your machine. Here is a quick overview of the process for each platform:
macOS and Linux
The recommended approach is to use a version manager like rbenv or asdf. This keeps your system Ruby untouched and lets you switch between Ruby versions easily.
# Install rbenv (macOS with Homebrew)
brew install rbenv ruby-build
# Install Ruby
rbenv install 3.3.0
rbenv global 3.3.0
# Verify Ruby is installed
ruby -v
# Install Rails
gem install rails
# Verify Rails is installed
rails -v
Windows
On Windows, the easiest option is the RubyInstaller. Download it from rubyinstaller.org, run the installer with the MSYS2 development toolchain, then open a new terminal and install Rails:
gem install rails
rails -v
For detailed installation instructions on all platforms, see the official Rails Getting Started guide.
Creating Your First Rails App
With Ruby and Rails installed, you are ready to create your first application. Rails provides a powerful generator that scaffolds an entire project for you:
# Create a new Rails application
rails new blog_app
# Move into the project directory
cd blog_app
# Start the development server
bin/rails server
Open your browser and visit http://localhost:3000. You should see the Rails welcome page confirming everything is working correctly.
Tip: The rails new command accepts many flags. Use rails new --help to see all options. For example, rails new blog_app --database=postgresql sets up PostgreSQL instead of the default SQLite.
Understanding the Project Structure
Rails follows the convention over configuration principle. Every file has a specific place and purpose. Here are the most important directories and files:
blog_app/
app/
controllers/ # Handle incoming requests and responses
models/ # Business logic and database interactions
views/ # HTML templates (ERB by default)
helpers/ # View helper methods
assets/ # Stylesheets, JavaScript, images
config/
routes.rb # URL routing definitions
database.yml # Database configuration
db/
migrate/ # Database migration files
schema.rb # Current database schema
Gemfile # Ruby gem dependencies
Gemfile.lock # Locked gem versions
The key concept to understand is MVC (Model-View-Controller). When a user makes a request, Rails routes it to a controller action, which interacts with the model (data layer) and renders a view (HTML response) back to the browser.
Routes, Controllers, and Views
Let us build a simple page to understand how these three pieces connect. First, define a route in config/routes.rb:
# config/routes.rb
Rails.application.routes.draw do
root "pages#home"
get "about", to: "pages#about"
end
This tells Rails to send requests for / to the home action and /about to the about action of the PagesController. Now generate the controller:
bin/rails generate controller Pages home about
This creates the controller file, view templates, and routes (though we already defined ours). Open the generated controller:
# app/controllers/pages_controller.rb
class PagesController < ApplicationController
def home
@title = "Welcome to My Blog"
end
def about
@title = "About Us"
end
end
Instance variables (prefixed with @) are automatically available in the corresponding view. Edit the home view:
<!-- app/views/pages/home.html.erb -->
<h1><%= @title %></h1>
<p>This is a simple blog built with Ruby on Rails.</p>
<%= link_to "About", about_path %>
The <%= %> tags evaluate Ruby code and output the result into the HTML. The link_to helper generates an anchor tag using a named route. Restart your server and visit the page to see it in action.
Models and Database Basics with ActiveRecord
Rails uses ActiveRecord as its ORM (Object-Relational Mapping). Instead of writing raw SQL, you work with Ruby objects that map directly to database tables. Let us create an Article model:
# Generate the model and migration
bin/rails generate model Article title:string body:text
# Run the migration to create the table
bin/rails db:migrate
This creates two important files: the model at app/models/article.rb and a migration in db/migrate/. The migration looks like this:
# db/migrate/XXXXXXXXXXXXXX_create_articles.rb
class CreateArticles < ActiveRecord::Migration[7.1]
def change
create_table :articles do |t|
t.string :title
t.text :body
t.timestamps
end
end
end
You can interact with your model immediately using the Rails console:
bin/rails console
# Create a new article
article = Article.new(title: "Hello Rails", body: "My first article!")
article.save
# Find all articles
Article.all
# Find by ID
Article.find(1)
# Update
article.update(title: "Hello Ruby on Rails")
# Delete
article.destroy
You can also add validations to your model to ensure data integrity:
# app/models/article.rb
class Article < ApplicationRecord
validates :title, presence: true, length: { minimum: 5 }
validates :body, presence: true
end
Building a Simple CRUD Feature Step by Step
CRUD stands for Create, Read, Update, Delete -- the four basic operations for managing data. Let us build full CRUD functionality for our articles. Start by adding resourceful routes:
# config/routes.rb
Rails.application.routes.draw do
root "articles#index"
resources :articles
end
The resources :articles line generates all seven RESTful routes. Run bin/rails routes to see them:
bin/rails routes
# Output:
# Prefix Verb URI Pattern Controller#Action
# articles GET /articles(.:format) articles#index
# POST /articles(.:format) articles#create
# new_article GET /articles/new(.:format) articles#new
# edit_article GET /articles/:id/edit(.:format) articles#edit
# article GET /articles/:id(.:format) articles#show
# PATCH /articles/:id(.:format) articles#update
# DELETE /articles/:id(.:format) articles#destroy
Now generate the controller with all the necessary actions:
bin/rails generate controller Articles index show new create edit update destroy
Replace the generated controller content with a full CRUD implementation:
# app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
before_action :set_article, only: [:show, :edit, :update, :destroy]
def index
@articles = Article.all.order(created_at: :desc)
end
def show
end
def new
@article = Article.new
end
def create
@article = Article.new(article_params)
if @article.save
redirect_to @article, notice: "Article was successfully created."
else
render :new, status: :unprocessable_entity
end
end
def edit
end
def update
if @article.update(article_params)
redirect_to @article, notice: "Article was successfully updated."
else
render :edit, status: :unprocessable_entity
end
end
def destroy
@article.destroy
redirect_to articles_path, notice: "Article was successfully deleted."
end
private
def set_article
@article = Article.find(params[:id])
end
def article_params
params.require(:article).permit(:title, :body)
end
end
The before_action callback loads the article for actions that need it. The article_params method uses strong parameters to whitelist allowed attributes, protecting against mass assignment vulnerabilities.
The Index View (List All Articles)
<!-- app/views/articles/index.html.erb -->
<h1>Articles</h1>
<%= link_to "New Article", new_article_path %>
<% @articles.each do |article| %>
<div>
<h2><%= link_to article.title, article_path(article) %></h2>
<p><%= truncate(article.body, length: 150) %></p>
<small>Published <%= time_ago_in_words(article.created_at) %> ago</small>
</div>
<% end %>
The Form Partial (Shared by New and Edit)
<!-- app/views/articles/_form.html.erb -->
<%= form_with(model: article) do |form| %>
<% if article.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(article.errors.count, "error") %> prevented saving:</h2>
<ul>
<% article.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div>
<%= form.label :title %>
<%= form.text_field :title %>
</div>
<div>
<%= form.label :body %>
<%= form.text_area :body, rows: 8 %>
</div>
<div>
<%= form.submit %>
</div>
<% end %>
The New and Edit Views
<!-- app/views/articles/new.html.erb -->
<h1>New Article</h1>
<%= render "form", article: @article %>
<%= link_to "Back to articles", articles_path %>
<!-- app/views/articles/edit.html.erb -->
<h1>Edit Article</h1>
<%= render "form", article: @article %>
<%= link_to "Back to articles", articles_path %>
The Show View (Single Article)
<!-- app/views/articles/show.html.erb -->
<h1><%= @article.title %></h1>
<p><%= @article.body %></p>
<%= link_to "Edit", edit_article_path(@article) %>
<%= link_to "Delete", article_path(@article),
data: { turbo_method: :delete, turbo_confirm: "Are you sure?" } %>
<%= link_to "Back to articles", articles_path %>
You now have a fully functional CRUD application. Start the server with bin/rails server, visit http://localhost:3000, and you can create, view, edit, and delete articles.
Strong parameters are a security feature in Rails. The article_params private method ensures that only the title and body fields can be set through forms. Any other attributes submitted by the user will be silently ignored.
Where to Go Next
Congratulations -- you have built your first Ruby on Rails application with full CRUD functionality! Here are some suggested next steps to continue learning:
- Add associations: Learn how to connect models (e.g., articles have many comments) using
has_manyandbelongs_to. - Authentication: Add user sign-up and login with gems like Devise or Rails 8's built-in authentication generator.
- Testing: Write tests with Minitest (built in) or RSpec. Testing is a core part of the Rails culture.
- Styling: Integrate Tailwind CSS, Bootstrap, or another CSS framework to make your app look professional.
- Background jobs: Use Active Job with Solid Queue or Sidekiq for tasks like sending emails.
- Deployment: Deploy your app to Heroku, Render, or Fly.io to share your work with the world.
Essential Resources
- Official Rails Guides -- comprehensive and always up to date.
- Rails API Documentation -- detailed reference for every module and method.
- RubyLearning's Ruby Tutorial -- strengthen your Ruby foundations.
- Useful gems: Explore RubyGems.org for libraries like Pundit (authorization), Pagy (pagination), and Ransack (search).
Accelerate Your Learning with AI Tools
Modern AI coding assistants can significantly speed up your Rails learning journey. Tools like GitHub Copilot, Cursor, and Claude can explain unfamiliar Rails conventions, generate boilerplate code, and help debug errors in real time. If you are curious about which AI coding tools work best for Ruby and Rails development, check out WhoCodes Best for independent comparisons of AI coding models across different programming tasks.
Combining hands-on practice with AI-assisted learning is one of the most effective ways to learn ruby on rails quickly. Build real projects, ask questions when you get stuck, and do not be afraid to experiment.
Remember: The best way to learn Ruby on Rails is by building. Start with the blog app from this tutorial, then expand it with new features. Every feature you add will deepen your understanding of the framework and its conventions.