type
status
date
slug
summary
tags
category
icon
password
notion image
ruby china wiki:https://ruby-china.org/wiki
Guides:

0. 前言

notion image
最近国内互联网就业市场持续低迷,作为主要着力于前端技术的我,也开始探索后端、部署相关的技术。之前除了接触过 Node.js,还有一门我一直想学习和应用的语言就是 Ruby 了。
第一次听说 Ruby 是在 2020 年的夏天,当时还是土木 🐶 的我,从前辈口中听说了 Ruby 这个词,他说他要亲自教我,但是没有天赋的我还是去土木和设计行业卷了一阵子才正式返航计算机。虽迟但到,在 2023 年的夏天,我写下这一篇快速入门,也算是一种重逢吧!
Ruby 同样是一门面向对象的语言,抛开性能不谈,它的语法非常简单,行文甚至比 Python 还要简洁,而且足够语义化,这也是我选择它的重要原因。Rails 作为 Ruby 的开发框架,和大部分其他语言框架一样采用 MVC 架构(附录 A 中我添加了 MVC 的说明),它提供了一些工具和函数来快速开发 Web 应用程序。另一方面,它还支持主流的数据库,比如:MySQL、PostgreSQL 和 SQLite 等。
目前,我正在开发一个 H5 小应用,数据库使用的是 PostgreSQL,总体体验下来,还算 OK,如果要问我,什么是 Rails?
Rails = Routes + MVC
以下是正文。

1. 创建 Rails API

安装 ruby 的过程我就省略了,安装完成后执行 ruby --version 来查看版本。

1.1 生成 rails api 服务

docker 容器中执行以下命令生成一个 rails api 服务
会报错,需要启动一个数据库,如下。

1.2 启动 postgres 数据库

宿主机终端执行以下命令启动一个 postgres 数据库(版本为 14)

1.3 连接数据库

配置开发环境变量,config/database.yml
重新运行 server

1.4 model 定义

user 是表名,email 和 name 是字段
生成数据库 migrate 文件以及 model 文件:
  • db/migrate/20230607152514_create_users.rb
    • app/models/user.rb

      1.5 数据库迁移同步

      将创建的 user 模型迁移到 postgres 数据库(会生成一个 users 表)

      1.6 controller 定义

      生成 users 的 controller,包括 show 和 create 方法
      生成 users 的控制器文件以及添加相应路由
      • app/controllers/users_controller.rb(源文件已做修改)
        • config/routes.rb(路由文件中会自动添加以下两行内容)
          • 路由文件需要修改,上面自动生成的两句删除不用,添加以下两句代码到 routes.rb 中:

        1.7 model 数据校验

        数据校验一般在 model 层进行。假设,需要对 users 表的 email 字段进行必填校验。
        那么在 app/models/users.rb 中添加以下代码即可:
        • validates :email 告诉它要校验的字段是 email
        • presence: true 校验规则是 email 必须到场(presence)

        2. RESTful API

        HTTP Method
        API Path
        Description
        GET
        api/v1/zoos
        列出所有动物园
        POST
        api/v1/zoos
        新建一个动物园
        GET
        api/v1/zoos/:id
        获取某个指定动物园的信息
        PUT
        api/v1/zoos/:id
        更新某个指定动物园的全部信息
        PATCH
        api/v1/zoos/:id
        更新某个指定动物园的部分信息
        DELETE
        api/v1/zoos/:id
        删除某个动物园
        GET
        api/v1/zoos/:id/animals
        列出某个指定动物园的所有动物
        DELETE
        api/v1/zoos/:id/animals/:id
        删除某个指定动物园的指定动物

        3. API 开发

        根据产品需求和 UI、UX 设计数据库与 API。

        3.1 路由表生成

        利用 namespace 构建以以 /api/v1 开头的 api 路由表:
        config/routes.rb
        生成路由表:bin/rails routes

        3.2 model > migrate > controller

        按照附录 A 依次创建 model、迁移数据库,创建 controller

        3.3 分页功能

        4. 单元测试(RSpec)- 过一遍,忘了就去问 chatGPT

        rspec # BDD for Rails(行为驱动开发)
        目的:对 model、controller 进行测试
        前提:需要一个测试环境的数据库
        现在已经有开发环境的数据库(catdou_dev)了,现在以这个数据库为例,做数据表的迁移。
        在迁移之前,需要配置并新建一个测试环境的数据库(catdou_test)。

        4.1 测试数据库:环境参数配置与新建

        环境参数配置
        config/database.yml
        新建数据库

        4.2 数据表迁移

        如果缺少 model,执行 rails 提供的 model 生成命令即可。

        4.3 rspec 依赖安装

        Add rspec-rails to both the :development and :test groups of your app’s Gemfile:
        Then, in your project directory:

        4.4 rspec 使用之 model 测试

        Creating boilerplate specs with rails generate: (如果 user 模型已经存在就不用重复生成了!直接运行第二个指令。)
        Running specs:
        🌰:测试 user 模型:rails generate rspec:model user
        之后会创建出一个 spec/models/user_spec.rb 文件(已改源码):
        运行测试用例:bundle exec rspec
        一个点代表一个测试用例成功执行。

        4.5 rspec 使用之 controller 测试

        🌰:测试 validation_codes controller:bin/rails g rspec:request validation_codes
        app/controllers/api/v1/validation_codes_controller.rb
        spec/requests/validation_codes_spec.rb

        附录

        附录A MVC 架构

        用户发送请求后,请求会进入 Controller 层。Controller 层负责接收和解析请求,处理业务逻辑,然后将数据传递给 Model 层进行处理。Model 层负责数据的读取、修改、删除等操作,并将处理后的结果保存到数据库或者其他服务中。最终,Controller 层将经过处理的数据返回给用户。整个过程中,View 层负责将数据渲染成最终的呈现形式(如 HTML 页面、JSON 响应等),但这并不是 MVC 模式的必要组成部分,因为 Ruby on Rails 中有一个概念叫做 Action View,它将 View 层的功能集成在了 Controller 层中,使得开发更加高效简洁。【以上绘图和回答来自 ChatGPT】

        A-1 view

        view 层,用于数据渲染和视图展示,用户访问路径时会向后端发送请求。

        A-2 controller

        controller 层,负责响应用户的请求(HTTP:GET、POST、PUT/PATCH、DELETE),这些请求通过路由映射到 controller 中,执行 CRUD 相关操作。
        • 从请求对象中获取参数
        • 访问 session,查看是否有权限
        • 执行查询操作
        • 响应类型:HTML 页面、JSON API 响应、文件下载等
        • CSRF(跨站点请求伪造)保护功能

        A-3 model

        model 层,用于数据处理和存储。比如:数据的验证、转换、过滤、存储。

        附录B curl 命令

        B-1 GET 请求

        B-2 POST 请求

        附录C VSCode 插件 - PostgreSQL

        postgresql explorer: postgresql

        附录D 快速构建 API

        前提:构建了 Rails 服务(并连接了数据库):rails new --api --database=postgresql --skip-test catdou-1

        D-1 routes

        第一步、routes,生成路由表: bin/rails routes
        🌰:利用 namespace 生成一个以 /api/v1 开头的 api 路由表:(对应 controller 文件要放在 controllers/api/v1 目录下)
        config/routes.rb

        D-2 model

        第二步、model,生成(User)模型并在数据库中生成(users)表:bin/rails g model user email:string name:string
        Tip:模型是单数,如:User,对应的数据库表名是复数,如:users
        • model file(User 模型相关,数据验证可以在这里做):app/models/user.rb
        • db migrate file(users 表对应的数据库迁移文件,相关的字段类型定义在这里设定,这个文件决定了如何创建数据表):20230607152514_create_users.rb
        为什么model 类是单数,而迁移文件的表会自动对应到复数?https://ruby-china.org/wiki/the-rails-doctrine
        和 Matz 一样,我有时候为了实现我的理念也会做出一些蠢事。一个例子便是 Inflector,一个可以对英文做不规则转化的类,譬如 Person 类对应到 People 表、Analysis 对应到 Analyses,Comment 对应到 Comments 等。这个东西现在已经是 Rails 不可分割的元素了,但早期争议的怒火延烧到今日,伤口仍未愈合,由此可见其重要性。
        以及指导手册上的 🌰
        • Model Class - Singular with the first letter of each word capitalized (e.g., BookClub).
        • Database Table - Plural with underscores separating words (e.g., book_clubs).
        Model / Class
        Table / Schema
        Article
        articles
        LineItem
        line_items
        Deer
        deers
        Mouse
        mice
        Person
        people

        D-3 migrate

        第三步、migrate,迁移文件,创建数据库表(users):bin/rails db:migrate
        • 如有失败,则在后面加上环境变量:bin/rails db:migrate RAILS_ENV=development
        • 数据库回滚:bin/rails db:rollback
        • 数据库删除:bin/rails db:drop

        D-4 controller

        第四步、controller,生成控制器(要写复数):bin/rails g controller Api::V1::Users show
        🌰:因为第一步的路由文件设置了 namespace,所以 controller 文件中第一行的 Class 类要以 Api::V1:: 开头!

        附录E HTTP 状态码

        HTTP 状态码
        含义
        备注
        200
        OK 成功
        201
        Created 创建成功
        资源创建成功
        404
        Not Found 未找到
        403
        Forbidden 拒绝授权
        401
        Unauthorized 未登录
        缺少身份验证凭证
        422
        Unprocessable Entity 无法处理,参数有问题
        402
        Payment Required 需付费
        412
        Precondition Failed 不满足前提条件
        429
        Too Many Requests 请求太频繁
        频次限制
        400
        Bad Request 其他错误请求
        错误详情放在 body 里
        • 4xx 为客户端错误
        • 5xx 为服务器错误

        附录F 数据类型

        1. string:字符串类型,用于表示文本数据。
        1. text:字符串类型,用于表示大文本数据。
        1. integer:整数类型,用于表示整数数据。
        1. float:浮点数类型,用于表示浮点数数据。
        1. decimal:高精度小数类型,用于表示精度比较高的小数数据。
        1. datetime:日期和时间类型,用于表示日期和时间数据。
        1. timestamp:时间戳类型,用于记录数据的创建和更新时间。
        1. time:时间类型,用于表示时间数据。
        1. date:日期类型,用于表示日期数据。
        1. binary:二进制类型,用于存储二进制数据,如图片等。
        1. boolean:布尔类型,用于表示真假数据。

        附录G Gem 使用

        Ruby 是“红宝石”的意思,而 Gem 是“宝石”的意思。
        notion image
        Gem 相当于 NPM,都是包管理器。
        Gemfile, Gemfile.lock 相当于 Node 项目中的 package.json, package-lock.json,描述了项目需要的依赖关系。
        但一般使用 bundle 来安装项目所需的所有 gem 包bundle installbundle(查看安装详情:bundle --verbose
        换国内的源,加速下载:打开 Gemfile,找到第一行,将默认的 source "https://rubygems.org" 换成 source "https://gems.ruby-china.com/"
        注意:每次安装完成后,因为依赖变了,和前端一样,需要重启一下服务!

        gem 常用指令:
        1. gem install <gem_name>:安装指定的 gem 包。
        1. gem uninstall <gem_name>:删除指定的 gem 包。
        1. gem update <gem_name>:更新指定的 gem 包。
        1. gem list:列出所有已安装的 gem 包。
        1. gem search <keyword>:搜索包含关键词的 gem 包。
        1. gem env:显示当前 gem 环境的配置信息。
        1. gem sources:列出所有可用的 gem 源。
        1. gem sources --add <source_uri>:添加一个新的 gem 源。
        1. gem help:查看 gem 命令的帮助信息。

        bundle 常用指令:
        • bundle install:根据 Gemfile.lock 文件中的依赖关系,安装所有需要的 gem 包。如果 Gemfile.lock 文件不存在,它会先生成这个文件,然后再进行安装。当然,如果我们在 Gemfile 中添加了新的依赖项,执行 bundle install 还会安装这些新的依赖项。
        • bundle update:检查 Gemfile 中的所有 gem 包的最新版本,并更新 Gemfile.lock 文件,同时安装更新后的 gem 包。
        • bundle exec:运行特定版本的 gem 包。如果你在多个项目间使用了不同版本的 gem 包,可以使用这个命令来使用指定项目的 gem 包。这个命令用法如下:
          • 其中 <command> 指运行的命令,例如 rails server 等。
        • bundle package:将项目所需的 gem 包打成 gem 包并放到 vendor/cache 目录下,方便离线安装。

        附录H zsh 常用命令

        zsh 是一种 Unix shell,是 Bourne shell(sh)的扩展,也是 Bash、Ksh 等 shell 的改进版。它提供了更多的功能和自定义选项,如支持自动补全、历史命令搜索、别名等。
        1. cd:切换当前工作目录
          1. ls:列出当前目录的文件和子目录
          1. pwd:显示当前所在的工作目录的完整路径
          1. alias:创建别名
          1. unalias:删除别名
          1. source:重新执行当前shell环境
          1. emacs:进入emacs编辑器模式
          1. vi:进入vi编辑器模式
          1. history:查看历史命令
          1. echo:输出文本信息
          1. grep:查找文件中的文本内容
          1. chmod:修改文件或目录的权限
          1. chown:修改文件或目录的所有者
          1. rm:删除文件或目录
          1. cp:复制文件或目录
          1. mv:移动文件或目录
          1. mkdir:创建新目录
          1. rmdir:删除空目录
          1. cat:查看文件内容
          1. touch:创建新空文件或更改文件的时间戳。
           
          以上,如有谬误,还请斧正,希望这篇文章对你有所帮助,感谢您的阅读~
           
          什么?!前端工程师还不会 Docker?记录一次 bin/rails db:migrate 报错
          Eric 见嘉
          Eric 见嘉
          Less is more.
          公告
          type
          status
          date
          slug
          summary
          tags
          category
          icon
          password
          💭
          合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。

          关于我
          土木转行的前端开发工程师,陆续分享技术干货。
          联系我
          微信公众号:见嘉 Being Dev