Ruby on Rails 快速入门2

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
简介: Ruby on Rails 快速入门2

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

rspec # BDD for Rails(行为驱动开发)

目的:对 model、controller 进行测试

前提:需要一个测试环境的数据库

现在已经有开发环境的数据库(catdou_dev)了,现在以这个数据库为例,做数据表的迁移。

在迁移之前,需要配置并新建一个测试环境的数据库(catdou_test)。

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

环境参数配置

config/database.yml

# 其他环境配置
test:
  <<: *default
  database: catdou_test
  username: catdou
  password: 123456
  host: db-for-catdou
# 其他环境配置

新建数据库

bin/rails db:create RAILS_ENV=test

4.2 数据表迁移

bin/rails db:migrate RAILS_ENV=test

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

4.3 rspec 依赖安装

Add rspec-rails to both the :development and :test groups of your app’s Gemfile:

# Run against this stable release
group :development, :test do
  gem 'rspec-rails', '~> 6.0.0'
end

Then, in your project directory:

# Download and install
$ bundle install
# Generate boilerplate configuration files
# (check the comments in each generated file for more information)
$ rails generate rspec:install
      create  .rspec
      create  spec
      create  spec/spec_helper.rb
      create  spec/rails_helper.rb

4.4 rspec 使用之 model 测试

Creating boilerplate specs with rails generate: (如果 user 模型已经存在就不用重复生成了!直接运行第二个指令。)

# RSpec hooks into built-in generators
$ rails generate model user
      invoke  active_record
      create    db/migrate/20181017040312_create_users.rb
      create    app/models/user.rb
      invoke    rspec
      create      spec/models/user_spec.rb
# RSpec also provides its own spec file generators
$ rails generate rspec:model user
      create  spec/models/user_spec.rb
# List all RSpec generators
$ rails generate --help | grep rspec

Running specs:

# Default: Run all spec files (i.e., those matching spec/**/*_spec.rb)
$ bundle exec rspec
# Run all spec files in a single directory (recursively)
$ bundle exec rspec spec/models
# Run a single spec file
$ bundle exec rspec spec/controllers/accounts_controller_spec.rb
# Run a single example from a spec file (by line number)
$ bundle exec rspec spec/controllers/accounts_controller_spec.rb:8
# See all options for running specs
$ bundle exec rspec --help

🌰:测试 user 模型:rails generate rspec:model user

之后会创建出一个 spec/models/user_spec.rb 文件(已改源码):

require "rails_helper"
RSpec.describe User, type: :model do
  it '有 email' do
    user = User.new email: 'eric@x.com' # 新建一个实例,有一个 email 为 'eric@x.com'
    expect(user.email).to eq('eric@x.com') # 期望A等于B
  end
end

运行测试用例:bundle exec rspec

$ bundle exec rspec
.
Finished in 0.11852 seconds (files took 4.61 seconds to load)
1 example, 0 failures

一个点代表一个测试用例成功执行。

4.5 rspec 使用之 controller 测试

🌰:测试 validation_codes controller:bin/rails g rspec:request validation_codes

app/controllers/api/v1/validation_codes_controller.rb

class Api::V1::ValidationCodesController < ApplicationController
  def create
    code = SecureRandom.random_number.to_s[2..7] # 随机数取6位
    validation_code = ValidationCode.new email: params[:email],
                                         kind: "sign_in",
                                         code: code
    if validation_code.save
      head 201
    else
      render json: { errors: validation_code.errors }
    end
  end
end

spec/requests/validation_codes_spec.rb

require "rails_helper"
RSpec.describe "ValidationCodes", type: :request do
  describe "POST validation_codes#create" do
    it "can be created" do
      post "/api/v1/validation_codes", params: { email: "eric@x.com" }
      expect(response).to have_http_status(201)
    end
  end
end


附录

附录A MVC 架构

+----------------------+
|   User's Request     |
+----------------------+
           |
           v
+----------------------+
|   Controller Layer   |
+----------------------+
           |
           v
+----------------------+
|    Model Layer       |
+----------------------+
           |
           v 
+-----------------------+
|   Database or Service |
+-----------------------+
           |
           v
+-----------------------+
|   Response to User    |
+-----------------------+

用户发送请求后,请求会进入 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 请求

curl http://127.0.0.1:3000/api/users/1
curl http://127.0.0.1:3000/api/users/1 -v # -v 表示 verbose 详细模式,请求头、响应头之类的会被打印出来

B-2 POST 请求

curl -X POST http://127.0.0.1:3000/api/users

附录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

Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do
      # /api/v1
      resources :validation_codes, only: [:create]
      resource :session, only: [:create, :destroy]
      resource :me, only: [:show]
      resources :items
      resources :tags
    end
  end
end

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 类是单数,而迁移文件的表会自动对应到复数?ruby-china.org/wiki/the-ra…

和 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).


微信截图_20230702173200.png


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:: 开头!

class Api::V1::UsersController < ApplicationController
end

附录E HTTP 状态码

developer.mozilla.org/zh-CN/docs/…


微信截图_20230702173211.png


  • 4xx 为客户端错误
  • 5xx 为服务器错误

附录F 数据类型

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

附录G Gem 使用

Ruby 是“红宝石”的意思,而 Gem 是“宝石”的意思。

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 包。
  2. gem uninstall <gem_name>:删除指定的 gem 包。
  3. gem update <gem_name>:更新指定的 gem 包。
  4. gem list:列出所有已安装的 gem 包。
  5. gem search <keyword>:搜索包含关键词的 gem 包。
  6. gem env:显示当前 gem 环境的配置信息。
  7. gem sources:列出所有可用的 gem 源。
  8. gem sources --add <source_uri>:添加一个新的 gem 源。
  9. 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 包。这个命令用法如下:
bundle exec <command>
  • 其中 <command> 指运行的命令,例如 rails server 等。
  • bundle package:将项目所需的 gem 包打成 gem 包并放到 vendor/cache 目录下,方便离线安装。

附录H zsh 常用命令

zsh 是一种 Unix shell,是 Bourne shell(sh)的扩展,也是 Bash、Ksh 等 shell 的改进版。它提供了更多的功能和自定义选项,如支持自动补全、历史命令搜索、别名等。

  1. cd:切换当前工作目录
cd ~ # 回到家目录
cd .. # 回到上层
cd - # 回到上一次
  • ls:列出当前目录的文件和子目录
  • pwd:显示当前所在的工作目录的完整路径
  • alias:创建别名
  • unalias:删除别名
  • source:重新执行当前shell环境
  • emacs:进入emacs编辑器模式
  • vi:进入vi编辑器模式
  • history:查看历史命令
  • echo:输出文本信息
  • grep:查找文件中的文本内容
  • chmod:修改文件或目录的权限
  • chown:修改文件或目录的所有者
  • rm:删除文件或目录
  • cp:复制文件或目录
  • mv:移动文件或目录
  • mkdir:创建新目录
  • rmdir:删除空目录
  • cat:查看文件内容
  • touch:创建新空文件或更改文件的时间戳。



相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
4月前
|
缓存 关系型数据库 数据库
上云一年烧320万美元,成功“下云”六个月后Ruby on Rails之父现身回了 14 个问题!...
上云一年烧320万美元,成功“下云”六个月后Ruby on Rails之父现身回了 14 个问题!...
25 1
|
5月前
|
SQL 前端开发 数据库
前端学 Ruby:熟悉Rails
前端学 Ruby:熟悉Rails
166 0
|
5月前
|
前端开发 Linux 数据库
前端学 Ruby:安装Ruby、Rails
前端学 Ruby:安装Ruby、Rails
75 0
|
7月前
|
Java Linux 应用服务中间件
在 Ruby on Rails 应用程序中重用 Java 代码
在 Ruby on Rails 应用程序中重用 Java 代码
|
9月前
|
移动开发 前端开发 关系型数据库
Ruby on Rails 快速入门1
Ruby on Rails 快速入门1
83 0
|
机器学习/深度学习 开发框架 Java
别梦依稀咒逝川,Ruby二十八年前|M1芯片Mac os系统配置Ruby(3.0.0) on Rails(6.1.1)开发环境
在每个开发者心里,都会有一门“最好”的语言,在这个世界的某个深处,在一些矫矫不群的人们心中,这门语言的名字叫做Ruby,它今年二十八岁了,历史和Java一样的悠久,但是它没有大厂背书、它的性能被开发者诟病、时至今日依然无法高效利用多核资源,甚至于它每年都要被“死亡”一次,相比于有太阳计算机系统、甲骨文、IBM 这些大公司支持的 Java,它是那么的一无所有,但是,它又拥有全世界最虔诚的“信徒”,拥有最活跃的开发者社区,这一切,又让它是那么的应有尽有。是的,这就是Rubyist的理念:有的时候,你想证明给一万个人看,到后来,你发现只得到了一个明白的人,那就够了。
别梦依稀咒逝川,Ruby二十八年前|M1芯片Mac os系统配置Ruby(3.0.0) on Rails(6.1.1)开发环境
|
JavaScript 前端开发 Java
基于Docker在Win10平台搭建Ruby on Rails 6.0框架开发环境
2023年,“非著名Web框架”--Ruby on Rails已经18岁了。在今年,Rails 6.0趋于完善,除了拿掉讨厌的Jquery,Webpacker 也成为默认前端打包方案,Sprockets 开始软着陆,未来很可能会和Jquery一样被彻底废弃,这就是历史的进程。
基于Docker在Win10平台搭建Ruby on Rails 6.0框架开发环境
|
开发框架 安全 Ruby
CVE-2018-3760 Ruby On Rails 路径穿越漏洞
CVE-2018-3760 Ruby On Rails 路径穿越漏洞
168 0
CVE-2018-3760 Ruby On Rails 路径穿越漏洞
|
安全 Ruby
CVE-2019-5418 Ruby on Rails 路径穿越与任意文件读取漏洞
CVE-2019-5418 Ruby on Rails 路径穿越与任意文件读取漏洞
181 0
CVE-2019-5418 Ruby on Rails 路径穿越与任意文件读取漏洞