Ruby on Rails 入门指南 – wiki基地


Ruby on Rails 入门指南:从零开始构建你的第一个 Web 应用

欢迎来到 Ruby on Rails 的世界!如果你渴望高效地构建 Web 应用,Rails 无疑是一个强大且令人愉悦的选择。它以“约定优于配置”(Convention over Configuration)和“不重复自己”(Don’t Repeat Yourself – DRY)为核心原则,极大地提高了开发效率。

本指南将带你一步步了解 Rails 的基本概念,环境搭建,创建第一个应用,并构建一个简单的功能模块。让我们开始这段激动人心的旅程吧!

什么是 Ruby on Rails?

Ruby on Rails(通常简称 Rails)是一个使用 Ruby 语言编写的开源 Web 应用开发框架。它提供了一套完整的工具、结构和库,用于构建数据库驱动的 Web 应用。

核心理念:

  1. 约定优于配置 (Convention over Configuration, CoC): Rails 对如何组织代码、命名文件、与数据库交互等方面设定了大量约定。开发者只需遵循这些约定,就能省去大量的配置工作。这使得 Rails 项目结构高度统一,易于理解和维护。
  2. 不重复自己 (Don’t Repeat Yourself, DRY): Rails 鼓励开发者避免编写重复的代码。通过模块化、抽象和各种内置机制(如 Helpers, Partials, Active Record 等),Rails 帮助你保持代码简洁和可维护。
  3. MVC 架构模式 (Model-View-Controller): Rails 严格遵循 MVC 设计模式,将应用程序的逻辑分解为三个相互关联的部分:
    • Model (模型): 负责处理数据和业务逻辑。在 Rails 中,Model 通常与数据库表进行交互(通过 Active Record),进行数据查询、验证、保存等操作。
    • View (视图): 负责用户界面的展示。它接收 Controller 传递的数据,并将其渲染成用户友好的 HTML 页面。Rails 常使用 Embedded Ruby (ERB) 或 Haml/Slim 等模板引擎。
    • Controller (控制器): 负责接收用户的请求,处理输入,调用 Model 进行数据处理,然后选择合适的 View 来响应用户。Controller 是 Model 和 View 之间的协调者。

为什么选择 Rails?

  • 开发效率极高: CoC 和 DRY 原则、大量的内置工具(生成器、Active Record、路由等)以及活跃的社区和丰富的 Gem(第三方库)使得 Rails 开发者能够快速构建应用。
  • 全栈框架: Rails 涵盖了 Web 开发的各个方面,从数据库到前端视图,提供了一站式解决方案。
  • 生态系统成熟: 经过多年的发展,Rails 拥有庞大的社区、高质量的文档以及海量可用的 Gem,几乎可以满足任何常见的 Web 开发需求。
  • 适合快速原型开发: Rails 的生成器和约定使得构建基本 CRUD(创建、读取、更新、删除)功能非常迅速。
  • 适合构建复杂应用: 许多大型、高流量的网站(如 Shopify, GitHub, Airbnb 等)都使用了 Rails,证明了其在构建复杂应用方面的能力。

前置准备

在安装 Rails 之前,你需要准备好一些基础环境:

  1. Ruby 语言: Rails 是用 Ruby 写的,所以你首先需要安装 Ruby。推荐使用 Ruby 版本管理器,如 RVM (Ruby Version Manager) 或 rbenv,它们可以让你轻松安装和管理多个 Ruby 版本。
    • RVM: 访问 https://rvm.io/ 查看安装指南。
    • rbenv: 访问 https://github.com/rbenv/rbenv 查看安装指南。
    • 选择其中一个安装即可。安装完成后,确保你安装了最新或推荐的 Ruby 版本(例如 3.x)。
    • 检查 Ruby 版本:在终端输入 ruby -v
  2. Bundler: Bundler 是一个 Ruby Gem,用于管理项目依赖(Gem)。它通常与 Ruby 一起安装,或者在安装 Rails 时会自动安装。
    • 检查 Bundler 版本:在终端输入 bundle -v
  3. 数据库: Rails 默认使用 SQLite,它是一个轻量级的嵌入式数据库,无需单独安装服务器,适合开发和测试。对于生产环境,通常会使用更强大的数据库,如 PostgreSQL 或 MySQL。本指南将使用默认的 SQLite。
  4. 文本编辑器或 IDE: 你需要一个代码编辑器。推荐使用功能丰富的编辑器,如 Visual Studio Code (VS Code)、Sublime Text、Atom 或专门的 Ruby IDE (如 RubyMine)。

安装 Rails

在你已经安装并设置好 Ruby 环境后,就可以安装 Rails Gem 了。打开你的终端或命令行工具,运行以下命令:

bash
gem install rails

这个命令会从 RubyGems.org 下载并安装最新版本的 Rails Gem 以及它所依赖的其他 Gem。安装过程可能需要一些时间。

安装完成后,验证 Rails 是否成功安装:

bash
rails -v

如果命令输出了 Rails 的版本号,说明安装成功了!

创建你的第一个 Rails 应用

现在,让我们使用 Rails 的生成器来创建一个新的 Web 应用项目。在终端中导航到你想要创建项目的目录,然后运行:

bash
rails new myapp

  • rails new 是创建新 Rails 应用的命令。
  • myapp 是你应用的名称,你可以换成任何你喜欢的名字(注意使用小写字母和下划线)。

这个命令会执行以下操作:

  1. 创建一个名为 myapp 的新目录。
  2. myapp 目录中生成 Rails 应用所需的所有文件和目录结构。
  3. 安装应用在 Gemfile 中声明的所有依赖 Gem(使用 Bundler)。

整个过程可能需要几分钟。完成后,进入新创建的应用目录:

bash
cd myapp

现在你的终端目录就切换到了 myapp 项目的根目录。

启动 Rails 服务器

Rails 自带一个轻量级的 Web 服务器 Puma,可以用于开发环境。在应用根目录下运行以下命令启动服务器:

bash
rails server

或者简写:

bash
rails s

服务器启动后,你会看到一些输出信息,其中会显示服务器正在监听的地址和端口,通常是 http://localhost:3000

打开你的 Web 浏览器,访问 http://localhost:3000。如果一切顺利,你将看到 Rails 的欢迎页面:“Yay! You’re on Rails!”。这意味着你的第一个 Rails 应用已经成功运行了!

要停止服务器,回到终端,按 Ctrl + C

理解 Rails 项目结构

一个标准的 Rails 应用目录结构如下:

myapp/
├── app/
│ ├── assets/ # 静态资源 (CSS, JavaScript, Images)
│ ├── channels/ # Action Cable (WebSocket) 相关代码
│ ├── controllers/ # 控制器代码
│ ├── helpers/ # 视图助手方法
│ ├── javascript/ # JavaScript 文件 (使用 Webpacker 或 jsbundling)
│ ├── mailers/ # 邮件发送相关代码
│ ├── models/ # 模型代码 (Active Record)
│ ├── views/ # 视图模板 (ERB, Haml 等)
│ └── ...
├── bin/ # 可执行脚本 (rails, rake 等)
├── config/ # 应用配置 (路由、数据库、环境等)
│ ├── environments/ # 不同环境 (development, test, production) 的配置
│ ├── initializers/ # 应用启动时运行的配置代码
│ ├── locales/ # 国际化 (I18n) 文件
│ ├── routes.rb # 应用路由定义
│ └── ...
├── db/ # 数据库相关 (迁移文件, schema.rb, seeds.rb)
│ ├── migrate/ # 数据库迁移文件
│ └── ...
├── lib/ # 自定义库文件
│ ├── assets/
│ └── tasks/ # Rake 任务
├── log/ # 应用日志
├── public/ # 静态文件 (例如:favicon.ico, 404.html)
├── storage/ # Active Storage 文件存储
├── test/ # 测试文件 (单元测试, 集成测试等)
├── tmp/ # 临时文件
├── vendor/ # 第三方代码 (不常用)
├── Gemfile # 项目依赖 Gem 列表
├── Gemfile.lock # 锁定 Gem 版本
├── Rakefile # Rake 任务定义文件
└── ...

对于初学者,最核心的目录是 app/,特别是 app/modelsapp/viewsapp/controllers,它们对应着 MVC 架构。config/routes.rbdb/migrate 也非常重要。

核心概念:MVC 模式详解

正如前面提到的,Rails 遵循 MVC 模式。让我们更深入地看看每个部分的作用:

Model (模型)

  • 位置: app/models/
  • 职责: 处理数据和业务逻辑。
  • 核心组件: Active Record 是 Rails 的 ORM (Object-Relational Mapping) 框架。它将数据库表映射为 Ruby 对象,让你使用 Ruby 代码来操作数据库,而无需编写原始 SQL 语句。
  • 功能:
    • 定义数据结构(通过数据库迁移)。
    • 执行数据库操作(查询、创建、更新、删除)。
    • 定义数据之间的关系(一对多、多对多等)。
    • 实现数据验证 (Validations)。
    • 包含与数据相关的业务逻辑。

例如,如果你有一个 users 表,Rails 会有一个 User 模型 (app/models/user.rb)。你可以这样操作它:

“`ruby

创建新用户

user = User.new(name: “Alice”, email: “[email protected]”)
user.save

查询用户

User.all # 所有用户
User.find(1) # id 为 1 的用户
User.where(name: “Alice”) # 名字为 Alice 的用户

更新用户

user = User.find(1)
user.update(email: “[email protected]”)

删除用户

user.destroy
“`

View (视图)

  • 位置: app/views/
  • 职责: 负责将数据呈现给用户,生成 HTML 响应。
  • 核心组件: 模板引擎,默认是 ERB (Embedded Ruby)。视图文件以 .html.erb 结尾。
  • 功能:
    • 展示 Controller 传递的数据。
    • 使用 Ruby 代码(嵌入在 <% ... %><%= ... %> 中)来控制展示逻辑(如循环遍历数据)。
    • 利用布局文件 (app/views/layouts/application.html.erb) 来定义页面公共结构(头部、尾部、导航等)。
    • 使用局部视图 (Partials, 文件名前加下划线 _) 来复用视图代码。

ERB 语法示例:

“`html+erb

所有文章

    <% @posts.each do |post| %>

  • <%= post.title %>

    <%= post.body %>

    <%= link_to '查看', post_path(post) %>

  • <% end %>

<%= link_to ‘创建新文章’, new_post_path %>
“`

  • <% ... %>: 执行 Ruby 代码,但不输出结果到 HTML。常用于控制流(循环、条件判断)。
  • <%= ... %>: 执行 Ruby 代码,并将结果输出到 HTML。常用于显示变量值、调用方法等。

Controller (控制器)

  • 位置: app/controllers/
  • 职责: 接收和处理用户请求,调用 Model 获取或处理数据,然后选择并渲染合适的 View 作为响应。
  • 核心组件: Action Controller。
  • 功能:
    • 解析请求参数 (params)。
    • 调用 Model 进行数据操作。
    • 准备数据 (@instance_variables) 供 View 使用。
    • 渲染视图 (render) 或重定向到其他页面 (redirect_to)。
    • 处理用户输入(如表单提交)。

Controller 通常包含一组 Action(方法),每个 Action 对应着一个用户的请求路径。常见的 Action 包括:

  • index: 显示资源列表。
  • show: 显示单个资源。
  • new: 显示创建新资源的表单。
  • create: 处理提交的新资源表单数据,创建资源。
  • edit: 显示编辑现有资源的表单。
  • update: 处理提交的编辑表单数据,更新资源。
  • destroy: 删除资源。

Controller 示例 (app/controllers/posts_controller.rb):

“`ruby
class PostsController < ApplicationController
def index
@posts = Post.all # 调用 Model 获取所有文章
end

def show
@post = Post.find(params[:id]) # 调用 Model 获取指定 id 的文章
end

def new
@post = Post.new # 创建一个新文章对象供表单使用
end

def create
@post = Post.new(post_params) # 使用安全参数创建新文章对象

if @post.save # 调用 Model 保存文章到数据库
  redirect_to @post, notice: '文章创建成功!' # 重定向到 show 页面
else
  render :new # 如果保存失败,重新渲染 new 视图并显示错误
end

end

# … edit, update, destroy actions …

private # 私有方法,仅供本 Controller 内部使用

def post_params
# 限制允许通过表单提交的参数,防止安全漏洞
params.require(:post).permit(:title, :body)
end
end
“`

Routing (路由)

  • 位置: config/routes.rb
  • 职责: 定义 URL 如何映射到 Controller 的 Action。
  • 核心组件: Action Dispatcher。

config/routes.rb 文件是你的 Web 应用的交通枢纽。它定义了当用户访问某个 URL 时,应该由哪个 Controller 的哪个 Action 来处理。

使用 resources 声明是一种快速定义标准 RESTful 路由的方式:

“`ruby

config/routes.rb

Rails.application.routes.draw do
# 定义一个首页,当访问 “/” 时,由 PagesController 的 home action 处理
root ‘pages#home’

# 为 posts 资源定义一组标准的 RESTful 路由 (index, show, new, create, edit, update, destroy)
resources :posts

# 你也可以单独定义路由
# get ‘/about’, to: ‘pages#about’
end
“`

resources :posts 会自动生成以下路由:

HTTP 方法 路径 作用 Controller#Action 助手方法
GET /posts 列出所有文章 posts#index posts_path
GET /posts/:id 显示单篇文章 posts#show post_path(@post)
GET /posts/new 显示创建文章表单 posts#new new_post_path
POST /posts 创建新文章 posts#create posts_path
GET /posts/:id/edit 显示编辑文章表单 posts#edit edit_post_path(@post)
PATCH/PUT /posts/:id 更新文章 posts#update post_path(@post)
DELETE /posts/:id 删除文章 posts#destroy post_path(@post)

这些助手方法(如 posts_path, new_post_path 等)在 Controller 和 View 中非常有用,用于生成对应的 URL,使得代码更易维护。

构建一个简单的博客功能 (CRUD)

现在,让我们把这些概念结合起来,在 myapp 应用中构建一个最简单的博客功能,实现文章的创建、查看、列表展示。

步骤 1: 创建文章资源

Rails 的生成器可以帮助我们快速创建 Model、Controller、数据库迁移和基本的视图文件。我们将使用 resource 生成器,它会生成 Model、Controller 和路由,以及一些基础的视图模板(但 scaffold 会生成更完整的 CRUD 视图)。对于学习目的,resource 是个不错的起点。

在应用根目录下(myapp/),运行以下命令:

bash
rails generate resource Post title:string body:text

  • rails generate resource:使用 resource 生成器。
  • Post:资源的名称(Model 和 Controller 的名称将基于此,Model 是单数 Post,Controller 是复数 Posts)。
  • title:string:为文章添加一个 title 属性,数据类型为字符串。
  • body:text:为文章添加一个 body 属性,数据类型为文本(通常用于存储较长的文本)。

这个命令会生成很多文件,输出如下:

invoke active_record
create db/migrate/xxxxxxxxxxxxxx_create_posts.rb # 数据库迁移文件
create app/models/post.rb # Model 文件
invoke controller
create app/controllers/posts_controller.rb # Controller 文件
invoke erb
create app/views/posts # 视图目录
invoke resource_route
route resources :posts # 在 config/routes.rb 中添加资源路由

步骤 2: 运行数据库迁移

上一步生成了一个数据库迁移文件(文件名类似 db/migrate/2023..._create_posts.rb),它定义了如何创建 posts 表。现在需要执行这个迁移,将表创建到数据库中。

bash
rails db:migrate

这个命令会查看 db/migrate 目录中所有未执行的迁移文件,并按照时间戳顺序执行它们。执行成功后,你的数据库中就有了 posts 表,包含 id (Rails 默认添加)、titlebodycreated_atupdated_at (Rails 默认添加) 字段。

你可以查看 db/schema.rb 文件,它反映了当前数据库的结构。

步骤 3: 配置路由

rails generate resource 命令已经自动在 config/routes.rb 中添加了 resources :posts。这为我们的 PostsController 定义了标准的 RESTful 路由。

我们还可以设置首页,让用户访问 http://localhost:3000 时直接看到文章列表。在 config/routes.rb 文件中,找到 resources :posts 那行,并在文件顶部(或其他合适位置)添加:

ruby
root 'posts#index'

这将把根路径 (/) 映射到 PostsControllerindex action。完整的 config/routes.rb 文件可能看起来像这样:

ruby
Rails.application.routes.draw do
root 'posts#index' # 设置首页为文章列表
resources :posts # 定义 posts 资源的 RESTful 路由
end

步骤 4: 编写 Controller 代码

虽然生成器创建了 app/controllers/posts_controller.rb 文件,但其中的 action 方法是空的。我们需要填充这些方法来处理请求和数据。

编辑 app/controllers/posts_controller.rb,内容如下:

“`ruby
class PostsController < ApplicationController
# GET /posts
def index
@posts = Post.all # 从数据库获取所有文章
# Rails 会自动渲染 app/views/posts/index.html.erb
end

# GET /posts/:id
def show
# 从数据库根据 ID 查找文章
# params[:id] 从路由中获取 :id 参数
@post = Post.find(params[:id])
# Rails 会自动渲染 app/views/posts/show.html.erb
end

# GET /posts/new
def new
@post = Post.new # 创建一个空的新文章对象,用于在视图中构建表单
# Rails 会自动渲染 app/views/posts/new.html.erb
end

# POST /posts
def create
@post = Post.new(post_params) # 使用安全参数创建新文章对象

if @post.save # 尝试将文章保存到数据库
  # 如果保存成功,重定向到 show 页面,并显示成功消息
  redirect_to @post, notice: '文章创建成功!'
  # @post 是一个 Post 对象,Rails 知道如何将它解析为 post_path(@post)
else
  # 如果保存失败(例如验证不通过),重新渲染 new 视图
  # @post 对象现在包含了错误信息
  render :new, status: :unprocessable_entity
end

end

# — 暂时不实现 edit, update, destroy,为了简单起见 —
# 实际应用中你需要实现这些 action

private # 私有方法,不能作为路由 action 访问

# 这个方法用于过滤从表单提交的参数,只允许白名单中的参数通过
# 这是一个重要的安全措施,称为 “Strong Parameters”
def post_params
params.require(:post).permit(:title, :body)
# params[:post] 应该是一个哈希,包含 title 和 body 键
# require(:post) 要求 params 中必须包含 :post 键
# permit(:title, :body) 只允许 :title 和 :body 参数
end
end
“`

步骤 5: 创建和编辑 View 文件

生成器在 app/views/posts/ 下创建了一个空目录。我们需要手动创建视图文件。

  • app/views/posts/index.html.erb (文章列表):

    “`html+erb

    文章列表

    <% @posts.each do |post| %>

    <%# 暂时隐藏编辑和删除链接 %>
    <%#

    <%#

    %>

    <% end %>

    标题 内容
    <%= post.title %> <%= post.body %> <%= link_to ‘查看’, post_path(post) %> <%= link_to ‘编辑’, edit_post_path(post) %> <%= link_to ‘删除’, post_path(post), method: :delete, data: { confirm: ‘确定删除吗?’ } %>

    <%= link_to ‘创建新文章’, new_post_path %>
    “`

  • app/views/posts/show.html.erb (单篇文章详情):

    “`html+erb

    <%= notice %>

    <%# 显示 Controller 中设置的 notice 消息 %>

    <%= @post.title %>

    <%= @post.body %>

    <%# 暂时隐藏编辑和返回链接 %>
    <%# <%= link_to ‘编辑’, edit_post_path(@post) %> #>
    <%= link_to ‘返回列表’, posts_path %>
    “`

  • app/views/posts/new.html.erb (创建新文章表单):

    “`html+erb

    创建新文章

    <%= render ‘form’, post: @post %> <%# 渲染一个局部视图 _form.html.erb %>

    <%= link_to ‘返回列表’, posts_path %>
    “`

  • app/views/posts/_form.html.erb (表单局部视图):
    为了避免代码重复(创建和编辑表单结构通常相似),我们创建一个局部视图 _form.html.erb 来包含表单的核心部分。文件名以 _ 开头表示它是局部视图。

    “`html+erb
    <%# 接收一个名为 post 的本地变量,其值来自渲染时传递的 post: @post %>
    <%= form_with(model: post) do |form| %>
    <% if post.errors.any? %> <%# 如果 Model 对象有验证错误 %>

    <%= pluralize(post.errors.count, “个错误”) %> 导致文章无法保存:

      <ul>
        <% post.errors.each do |error| %>
          <li><%= error.full_message %></li>
        <% end %>
      </ul>
    </div>
    

    <% end %>

    <%= form.label :title %> <%# 标签 %>
    <%= form.text_field :title %> <%# 文本输入框 %>

    <%= form.label :body %>
    <%= form.text_area :body %> <%# 文本区域 %>

    <%= form.submit %> <%# 提交按钮 %>

    <% end %>
    “`

步骤 6: 添加 Model 验证 (可选但推荐)

为了确保数据质量,我们可以在 Model 中添加验证。例如,要求文章标题不能为空。

编辑 app/models/post.rb 文件:

ruby
class Post < ApplicationRecord
# 验证 title 字段不能为空
validates :title, presence: true
# 你可以添加更多验证,比如 body 长度限制等
# validates :body, length: { minimum: 10 }
end

现在,如果你尝试创建一个没有标题的文章,保存将会失败,并且 $post.errors 会包含错误信息,这些错误信息会在 _form.html.erb 局部视图中显示出来。

步骤 7: 运行应用并测试

确保你在 myapp/ 目录下,然后启动 Rails 服务器:

bash
rails s

打开浏览器访问 http://localhost:3000

  1. 你应该看到文章列表页面,最初是空的。
  2. 点击“创建新文章”链接。
  3. 填写标题和内容,点击“创建 Post”按钮。
  4. 如果成功,你会被重定向到文章详情页,并看到“文章创建成功!”的提示。
  5. 如果尝试提交空标题,你会看到错误信息。
  6. 返回列表页,你会看到新创建的文章。
  7. 点击文章标题旁边的“查看”链接,可以再次进入详情页。

恭喜!你已经成功构建了一个具备基本 CRUD 功能的 Web 应用模块!

进阶学习方向

你刚刚迈出了 Rails 开发的第一步。Rails 还有很多强大的功能等待你去探索:

  • 布局 (Layouts): 如何使用 app/views/layouts/application.html.erb 文件定义页面的公共结构。
  • 局部视图 (Partials): 如何创建和使用以 _ 开头的局部视图来复用代码。
  • 助手方法 (Helpers): 如何在 app/helpers/ 目录中编写 Ruby 方法,供视图中使用,保持视图简洁。
  • 资产管道 (Asset Pipeline): Rails 如何管理静态资源(CSS, JavaScript, Images)。
  • 用户认证 (Authentication) 和授权 (Authorization): 如何处理用户注册、登录、权限控制(推荐使用 Devise 等 Gem)。
  • 关系 (Associations): 模型之间的各种关系(一对多、多对多等)以及 Active Record 提供的强大关联操作。
  • 后台任务 (Background Jobs): 如何处理耗时任务,避免阻塞 Web 请求(Sidekiq, Delayed Job 等 Gem)。
  • 测试 (Testing): Rails 内置了 Minitest,也可以使用更强大的 RSpec 进行测试驱动开发 (TDD)。
  • RubyGems: 如何查找和使用成千上万的第三方 Gem 来扩展应用功能。
  • 部署 (Deployment): 如何将你的 Rails 应用发布到互联网上(Heroku, DigitalOcean, AWS 等)。
  • API 开发: Rails 也非常适合构建 RESTful API。

学习资源推荐

  • Ruby on Rails 官方指南 (Rails Guides): 这是最权威、最全面的学习资料,详细解释了 Rails 的各个方面。 https://guides.rubyonrails.org/ (有中文翻译版本,但可能非最新)
  • Rails Girls 指南: 非常适合绝对的初学者,通过创建一个简单的应用来学习 Rails。 http://guides.railsgirls.org/ (有中文版本)
  • Rails Tutorial by Michael Hartl: 一本非常受欢迎的免费在线书籍,通过构建一个完整的应用来深入学习 Rails。 https://www.railstutorial.org/ (有中文翻译版本)
  • Stack Overflow: 遇到问题时,这里是寻找答案的好地方。
  • Ruby China 社区: 国内活跃的 Ruby 和 Rails 社区,有很多资源和讨论。 https://ruby-china.org/

总结

通过本指南,你应该对 Ruby on Rails 有了一个初步的认识,包括其核心理念、MVC 架构、基本项目结构以及如何创建和运行一个简单的应用。你已经亲手构建了一个基础的博客功能,体验了 Rails 高效的开发流程。

Rails 是一个功能强大且富有表现力的框架,掌握它需要时间和实践。勇敢地去探索,尝试构建更多功能,阅读官方文档和高质量教程,参与社区讨论。祝你在 Rails 的世界里开发愉快!

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部