【山竹记账后端】1.搭建后端项目

从无到有创建 Rails API


大纲链接 §

[toc]


1. 初始化目录

前提:已经创建好 oh-my-env 的容器环境,打开容器项目

  • 已预装 ruby@3.0.0p0 或者 rvm use 3.1.2
  • 已预装 gem@3.2.3
  • 已预装 bundle@2.5.23
  • 已预装 rvm@1.29.12

还需要配置安装的:

  • gembundle 的源未配置国内镜像
  • rails 未安装
  • postgresql 未安装

命令行步骤

  • VSCode 中启动 oh-my-env 的容器环境
  • 无需重新 build

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    
    # 更换gem国内源
    gem sources --add https://mirrors.tuna.tsinghua.edu.cn/rubygems/ --remove https://gems.ruby-china.com/
    # 更换bundle国内源
    bundle config set --global mirror.https://rubygems.org https://mirrors.tuna.tsinghua.edu.cn/rubygems
    # 安装rails,版本尽量和我的一致,会有日志,等待时间较长
    gem install rails -v 7.2.3.2
    # 安装postgresql驱动
    pacman -S postgresql-libs
    # 创建rails项目;只是用 api 模式;数据库 使用 postgresql;跳过自带测试(之后使用第三方测试);
    cd ~/repos
    rails new --api --database=postgresql --skip-test mangosteen-1
    # 使用 VSCode 打开在容器中项目
    code mangosteen-1 # code ~/repos/mangosteen-1
    # 新建一个zsh终端后,启动rails服务;需要关闭server 请按Ctrl+C
    bundle exe rails server
  • 如果报错 gem:14: command not found: gem,需要切一下版本 rvm use 3 或者 rvm use 3.1.2

  • 安装rails,版本尽量和我的一致 rails -v 7.2.3.2,更新到稳定版

  • rails new --api --database=postgresql --skip-test mangosteen-1 参数解释

    • rails new 创建框架新项目
    • --api 只是用 api 模式
    • --database=postgresql 指定使用 PostgreSQL 数据库
    • --skip-test 跳过自带测试(之后使用第三方测试)
    • mangosteen-1 创建的项目目录名称
  • rails new 创建项目还需要安装另外的依赖,需要等待时间较长

    • 提示运行 bundle binstubs bundler前,需要先进入项目目录 cd mangosteen-1
    • 进入后可以看到已经创建了一堆项目文件,已经 git init,但还没有提交
  • 使用 VSCode 打开在容器中项目,由于全局环境和项目环境会有不一致,需要保证在项目中运行

  • 启动rails服务 bundle exec rails server 或者 bundle exe rails server

    • 可以简写为 bundle exec rails s
    • 也可以简写为 bin/rails s
    • 不推荐 rails s,因为全局环境和项目环境软件版本可能不一致
    • 项目中的 rails 版本在 Gemfile 中指定 gem "rails", "~> 7.2.3", ">= 7.2.3.2"
  • 启动后可以看到终端 => Booting Puma

    • Min threads:5 最小进程数
    • Max threads:5 最大进程数
    • Environment:development 默认环境为开发环境
    • Listening on http://127.0.0.1:3000 默认监听端口 3000,自动转发到 win 系统中
  • 直接访问 http://127.0.0.1:3000 会看到报错 ActiveRecord::ConnectionNotEstablished

    • 这是因为数据库没有启动,需要先启动数据库,定位报错信息 PGSQL.5432,需要执行docker命令来启动

国内源

  • 清华镜像 https://mirrors.tuna.tsinghua.edu.cn/rubygems/
  • 南阳镜像 https://mirror.nyist.edu.cn/rubygems/

参考


2. 启动数据库

1
docker run -d --name db-for-mangosteen -e POSTGRES_USER=mangosteen -e POSTGRES_PASSWORD=123456 -e POSTGRES_DB=mangosteen_dev -e PGDATA=/var/lib/postgresql/data/pgdata -v mangosteen-data:/var/lib/postgresql/data --network=network1 postgres:14
  • 命令不可折行,会有bug,以下为参数说明
    • docker run -d 启动一个新容器,-d 后台保持运行
    • --name db-for-mangosteen 命名该容器的名称
    • e POSTGRES_USER=mangosteen 环境变量:用户名
    • e POSTGRES_PASSWORD=123456 环境变量:密码
    • e POSTGRES_DB=mangosteen_dev 环境变量:数据库名称
    • 以区分测试环境mangosteen_test和生产环境mangosteen_production的数据库
    • e PGDATA=/var/lib/postgresql/data/pgdata 环境变量:PostgreSQL 数据目录,官方指定
    • v mangosteen-data:/var/lib/postgresql/data 挂载数据卷,将主机上的数据挂载到容器中
    • 自动创建并持久化数据卷,容器重启后数据不会丢失
    • --network=network1 指定网络,可以通过 db-for-mangosteen 这个名称来访问网络
    • postgres:14 镜像名称与版本号
  • 这行命令需要在 windows (docker的外部)系统中运行
  • 命令运行后会返回一串哈希,说明数据库已经启动
  • 此时在 docker desktop 中可以看到数据库容器正在运行
  • 可以通过 docker ps 查看数据库容器是否启动

3. 连接数据库

修改 config/database.yml 配置开发数据库

1
2
3
4
5
6
7
development:
  # noinspection YAMLUnresolvedAlias
  <<: *default
  database: mangosteen_dev
  username: mangosteen
  password: 123456
  host: db-for-mangosteen
  • 数据库名称 database: mangosteen_dev
  • 用户名 username: mangosteen
  • 密码 password: 123456
  • 主机名 host: db-for-mangosteen,理论上应填写一个ip或域名,这里填写的是容器名称
    • 这是之前运行容器的参数 docker run -d --name db-for-mangosteen ...

运行 sever

  • 此时需要按 Ctrl+C 先断开之前的服务,重新启动 bin/rails s

看到以下界面说明已经成功启动服务

rails

对于一个熟练的 ruby 程序员来说,主要步骤就三步

  • 创建目录
  • 启动数据库
  • 配置数据库,刷新

记得及时提交代码


4. rails 项目的选择

  • 创建时使用 api 模式
  • 数据库 使用 postgresql
  • 跳过自带测试(之后使用第三方测试)

rails的理念:约定大于配置,即直接给到最佳实践


5. 实现一个后台功能

简单实现一个后台功能,看看完整过程时怎样的

设计数据库

山竹记账需要哪些数据?

设计数据库的两种思路

  • 自上而下:现想大概,再添加细节
    • 大概有哪些表,有那些数据字段
  • 自下而上:用到什么加什么,会出现打脸的情况
  • 两种思路可以混合,我们先采用 自下而上

rsils提供的设计数据库工具

  • 建模工具:bin/rails g model user email:string name:string
    • g 代表 generate 会自动生成模型类迁移文件
    • 模型类: app/models/user.rb 文件
    • 迁移文件: db/migrate/YYYYMMDD_create_users.rb 文件
    • YYYYMMDD 为当前日期,用于区分不同的迁移文件
    • 需要自行填充 change 方法的逻辑
  • 数据库操作工具:ActiveRecord::Migration
    • 命令为 bin/rails g migration create_users_table
  • 同步到数据库:bin/rails db:migrate
  • 反悔命令:bin/rails db:rollback step=1
    • step=1 表示回滚最近一次迁移

rsils创建新建数据库代码

在进行数据库相关操作前,确保当前代码都已提交

1
2
3
4
bin/rails g model user email:string name:string
# invoke  active_record
# create    db/migrate/20260906082930_create_users.rb
# create    app/models/user.rb

查看 app/models/user.rb

1
2
class User < ApplicationRecord
end

查看 db/migrate/20260906082930_create_users.rb

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class CreateUsers < ActiveRecord::Migration[7.2]
  def change
    create_table :users do |t|
      t.string :email, limit: 100
      t.string :name

      t.timestamps
    end
  end
end
  • 声明类 class CreateUsers < ActiveRecord::Migration[7.2]
    • Migration[7.2] 表示使用 rails 7.2 版本的迁移类
  • def change 代表对数据库做的变动
    • create_table :users do |t| 创建一个名为 users 的表
    • t.string :email 添加一个字符串类型的 email 字段
    • t.string :name 添加一个字符串类型的 name 字段
    • t.timestamps 会自动添加 created_atupdated_at 字段,用于记录创建时间和更新时间

参考

目前并没有直接变更数据库,只是把将要变更的写到代码中,需要运行 bin/rails db:migrate 才会变更数据库。

rsils第一次迁移数据库

运行 bin/rails db:migrate 后,数据库会自动创建 users

1
2
3
4
5
6
bin/rails db:migrate

# == 20260906082930 CreateUsers: migrating ======================================
# -- create_table(:users)
#    -> 0.0393s
# == 20260906082930 CreateUsers: migrated (0.0394s) =============================

rsils反悔迁移数据库

运行 bin/rails db:rollback 可以回滚所有迁移 运行 bin/rails db:rollback step=1 可以回滚最近一次迁移

1
2
3
4
5
6
bin/rails db:rollback

# == 20260906082930 CreateUsers: reverting ======================================
# -- drop_table(:users)
#    -> 0.0076s
# == 20260906082930 CreateUsers: reverted (0.0138s) =============================
  • 自动识别之前 create_table 的反操作为 drop_table 删除

6. 创建路由

config/routes.rb

1
2
3
4
...
get '/users/:id', to: 'users#show'
post '/users', to: 'users#create'
...

手动添加路由(原始)

config/routes.rb

1
2
3
4
5
6
Rails.application.routes.draw do
  # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html

  post '/users', to: 'users#create'
  get '/users/:id', to: 'users#show'
end
  • to: 'users#create' 表示将 POST 请求路由到 UsersControllercreate 方法
  • to: 'users#show' 表示将 GET 请求路由到 UsersControllershow 方法

目前还未实现 createshow 这两个方法

  • 实现前别忘记提交代码

实现 createshow 这两个方法

1
2
3
4
5
bin/rails g controller users create show

# create  app/controllers/users_controller.rb
#  route  get "users/create"
#  get "users/show"
  • 注意 users 不要写错成 user
    • 确保文件名为 users_controller.rb
    • 确保类名为 UsersController
  • 自动创建了 app/controllers/users_controller.rb 文件
  • config/routes.rb 中自动添加了路由 get "users/create"get "users/show"
    • 不够精确,删除

app/controllers/users_controller.rb

1
2
3
4
5
6
7
8
9
class UsersController < ApplicationController
  def create
    p "你访问了 create"
  end

  def show
    p "你访问了 show"
  end
end
  • 添加打印日志,验证当用户访问这两个接口时,确实走了这两个方法的逻辑
  • 先确保服务已经启动
  • 另外打开一个终端,使用 curl 命令访问api接口,成功运行,可以在puma控制台看到输出
    • curl -X POST http://127.0.0.1:3000/users
    • curl -X GET http://127.0.0.1:3000/users/1

config/routes.rb

1
2
3
4
5
6
7
8
Rails.application.routes.draw do
  # get "user/create"
  # get "user/show"
  # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html

  post '/users', to: 'users#create'
  get '/users/:id', to: 'users#show'
end

调试填充逻辑 app/controllers/users_controller.rb

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class UsersController < ApplicationController
  def create
    user = User.new email: 'frank@x.com', name: 'frank'
    if user.save
      p 'save 成功了'
    else
      p 'save 失败了'
    end
  end

  def show
    p "你访问了 show"
  end
end

安装VSCode插件查看数据库,验证是否成功创建表


自动添加路由


7. $3


8. $3

小结:需要运行的命令参考

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 更换gem国内源
gem sources --add https://mirrors.tuna.tsinghua.edu.cn/rubygems/ --remove https://gems.ruby-china.com/
# 更换bundle国内源
bundle config set --global mirror.https://rubygems.org https://mirrors.tuna.tsinghua.edu.cn/rubygems
# 安装rails,版本尽量和我的一致,会有日志,等待时间较长
gem install rails -v 7.2.3.2
# 安装postgresql驱动
pacman -S postgresql-libs
# 创建rails项目;只是用 api 模式;数据库 使用 postgresql;跳过自带测试(之后使用第三方测试);
cd ~/repos
rails new --api --database=postgresql --skip-test mangosteen-1
# 使用 VSCode 打开在容器中项目
code mangosteen-1 # code ~/repos/mangosteen-1
# 启动数据库容器
docker run -d --name db-for-mangosteen -e POSTGRES_USER=mangosteen -e POSTGRES_PASSWORD=123456 -e POSTGRES_DB=mangosteen_dev -e PGDATA=/var/lib/postgresql/data/pgdata -v mangosteen-data:/var/lib/postgresql/data --network=network1 postgres:14
# 新建一个zsh终端后,启动rails服务;需要关闭server 请按Ctrl+C
bundle exec rails server

# 创建数据库模型类
bin/rails g model user email:string name:string
# 创建迁移文件
bin/rails g migration create_users_table
# 迁移数据库
bin/rails db:migrate
# 反悔迁移数据库
bin/rails db:rollback step=1

·未完待续·

参考文章

源代码镜像服务

数据迁移


相关文章


  • 作者: Joel
  • 文章链接:
  • 版权声明
  • 非自由转载-非商用-非衍生-保持署名