50 phút
Giới thiệu Ruby on Rails
Rails là gì?
Rails là framework web full-stack viết bằng Ruby, nổi tiếng với triết lý "Convention over Configuration" và "Don't Repeat Yourself".
Ưu điểm
- Convention over Configuration: Ít config, nhiều convention
- ActiveRecord ORM: ORM mạnh mẽ
- Scaffolding: Tạo CRUD nhanh
- Migration: Quản lý schema
- Testing: Tích hợp sẵn
- Hotwire: Modern frontend không cần nhiều JS
Cài đặt
Yêu cầu
- Ruby 3.2+
- Rails 7+
- Node.js (cho asset pipeline)
- Database (PostgreSQL khuyến nghị)
Install Ruby
# macOS với rbenv
brew install rbenv ruby-build
rbenv install 3.3.0
rbenv global 3.3.0
# Ubuntu
sudo apt install ruby-full
Install Rails
gem install rails
rails --version
Tạo project
rails new myapp --database=postgresql
cd myapp
bin/rails db:create
bin/rails server
Cấu trúc project
myapp/
├── app/
│ ├── controllers/
│ ├── models/
│ ├── views/
│ ├── helpers/
│ ├── jobs/
│ ├── mailers/
│ └── assets/
├── config/
│ ├── routes.rb
│ ├── database.yml
│ └── initializers/
├── db/
│ ├── migrate/
│ ├── schema.rb
│ └── seeds.rb
├── lib/
├── public/
├── test/ (hoặc spec/)
├── Gemfile
└── Gemfile.lock
MVC Flow
Request → Routes → Controller → Model → View → Response
↓
Database
Scaffolding
Tạo full CRUD
rails generate scaffold Post title:string body:text published:boolean
rails db:migrate
Điều này tạo ra:
- Model, Migration
- Controller với 7 actions
- Views (index, show, new, edit)
- Routes
- Tests
Controller cơ bản
# app/controllers/posts_controller.rb
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
def index
@posts = Post.all
end
def show
end
def new
@post = Post.new
end
def create
@post = Post.new(post_params)
if @post.save
redirect_to @post, notice: 'Post was successfully created.'
else
render :new, status: :unprocessable_entity
end
end
def update
if @post.update(post_params)
redirect_to @post, notice: 'Post was successfully updated.'
else
render :edit, status: :unprocessable_entity
end
end
def destroy
@post.destroy
redirect_to posts_url, notice: 'Post was successfully destroyed.'
end
private
def set_post
@post = Post.find(params[:id])
end
def post_params
params.require(:post).permit(:title, :body, :published)
end
end
Routes
# config/routes.rb
Rails.application.routes.draw do
root 'home#index'
resources :posts
resources :users, only: [:index, :show]
# Nested routes
resources :posts do
resources :comments, only: [:create, :destroy]
end
# API namespace
namespace :api do
namespace :v1 do
resources :posts
end
end
# Custom routes
get '/about', to: 'pages#about'
post '/contact', to: 'pages#contact'
end
Rails Console
bin/rails console
# hoặc ngắn gọn
bin/rails c
# Trong console
Post.all
Post.first
Post.where(published: true)
post = Post.new(title: 'Hello')
post.save
Generators
# Model
rails g model Product name:string price:decimal stock:integer
# Controller
rails g controller Products index show
# Migration
rails g migration AddPublishedToPosts published:boolean
# Scaffold
rails g scaffold Category name:string
Bài tập thực hành
Hãy tạo ứng dụng blog đơn giản với scaffold!