Rails 7 开发总结(下)

877 阅读4分钟

1. 在 Controller 中操作数据

数据库中的每一行都是一个 ActiveRecord 对象,通过对象自带的方法进行 CRUD。每一列是当前对象的属性。

excel

1.1 新增

user = User.new # 新建
user.email = '1@x.com'
user.password = 'x'

user = User.new(email: '1@x.com', password: 'x') # 上面简化为这一句
user.save # 保存到数据库
user.errors # 保存失败

user = User.create(email: '1@x.com', password: 'x') # 新建+保存

# 使用params.permit(:email, :password)从params中选定字段
user = User.new(params.permit(:email, :password))
user.save

user = User.create(params.permit(:email, :password))

1.2 查询

users = User.all

users = User.where(email: '1@x.com') # 查找邮箱为...

users = User.where.not(email: '1@x.com') # 查找邮箱不为...

users = User.all.limit(3).order(created_at: :asc) # 获取前三个按创建时间升序排列的用户数据

1.3 更新

user = User.find_by(email: params[:email])
if user
  user.email = params[:email]
  user.save
end

# 或者直接调用 update 方法更新
user.update(email: params[:email])

1.4 删除

user = User.find(params[:id])
if user
  user.destroy
end

2. Model 数据验证

在存入数据库前对资源字段进行验证,如果验证失败就不会存进去。

class User < ApplicationRecord
  has_secure_password # 内置的宏命令
  
  # 存入数据前校验email:必填、唯一、格式
  validates :email, presence: true, uniqueness: true, format: {with: /\A.+@.+\z/}
end

has_secure_password 是Rails中内置的宏命令,自动添加特性:密码的验证和加密。

3. 返回 json 数据

3.1 基本用法

user = User.new(params.permit(:email, :password))
if user.save
  # 保存成功,返回 json 数据、HTTP 状态码
else
  # 保存失败(如字段验证失败),错误以列表形式保存在 user.errors.full_messages
end

3.2 HTTP 状态码

Ruby符号HTTP状态码描述
:ok200 OK成功处理了请求的标准响应。
:created201 Created请求已经被实现,而且有一个新的资源已经依据请求的需要而建立。
:accepted202 Accepted请求已被接受用于处理,处理并未完成。
:no_content204 No Content服务器成功处理了请求,但没有返回任何内容。
:moved_permanently301 Moved Permanently请求的URL已移走。
:found302 Found临时的响应会经常变动,如会换一个URL。
:bad_request400 Bad Request服务器不理解请求的语法。
:unauthorized401 Unauthorized请求要求用户的身份认证。
:forbidden403 Forbidden服务器理解请求客户端的请求,但是拒绝执行此请求。
:not_found404 Not Found服务器无法根据客户端的请求找到资源。
:unprocessable_entity422 Unprocessable Entity请求格式正确,但是由于含有语义错误,无法响应。
:too_many_requests429 Too Many Requests用户在给定的时间内发送了太多的请求。
:internal_server_error500 Internal Server Error服务器内部错误,无法完成请求。

3.3 实例

class Api::V1::UsersController < ApplicationController
	# 注册
	def create
	  user = User.new(user_params)
	  if user.save
	    render json: {
	      status: 'success',
	      message: '注册成功',
	    }, status: :created # 201
	  else
	    render json: {
	      status: 'failure',
	      message: user.errors.full_messages.join(', ')
	    }, status: :unprocessable_entity # 422
	  end
	end
	
	private
  def user_params
    params.permit(:email, :password, :password_confirmation)
  end
end

private 用于定义类的私有方法,只能在类内部使用。

4. 数据序列化

在数据库中查到的数据默认是所有的属性都会被返回出来的,通过序列化器返回指定属性。

4.1 依赖安装

在 Gemfile 中添加:

gem 'active_model_serializers'

执行 bundle install 安装依赖。

4.2 创建序列化器

rails g serializer User

在 app/serializers 下生成 user_serializer.rb:

class UserSerializer < ActiveModel::Serializer
  attributes :id, :email, :name, :address, :phone
end

4.3 全局序列化方法封装

controller 目录下有一个 application_controller.rb,在这里可以共享方法和行为。

# 序列化
def serialize_resource(resource)
  ActiveModelSerializers::SerializableResource.new(resource).as_json
end

4.4 返回 json 时使用序列化器

def index
	apples = Apple.not_deleted.all
	return render json: {
		status: 'sucess',
		message: '获取成功',
		data: serialize_resource(apples)
	}, status: :ok
end

4.5 as_json

简单的序列话可以用 as_json 方法代替。

user = User.find(1)
user.as_json(only: [:id, :email, :name, :address, :phone])

5. 软删除

软删除不是真正的删除,是对记录做一个标记。

5.1 定义

class Apple < ApplicationRecord
  # 自定义范围,返回未被删除的记录
  scope :not_deleted, -> { where(deleted_at: nil) }

	# 多个字段必填
  validates_presence_of :name, :price, :discount, :tag

  # 可以通过 apple.soft_delete 来软删除一个 apple 对象
  def soft_delete
    update(deleted_at: Time.current)
  end
  
  # 过滤掉 delete_at 属性
  def as_filtered_json
    self.as_json(except: [:deleted_at])
  end
end

5.2 使用

在 Controller 中使用。

Apple.not_deleted 等价于 Apple.where(deleted_at: nil)

# 获取所有未删除的数据
apples = Apple.not_deleted.all

软删除的使用:

apple = Apple.find(id)
apple.soft_delete # 执行软删除

6. CORS

解决跨域问题。

6.1 安装依赖

在 Gemfile 中添加:

gem "rack-cors"

执行 bundle install 安装依赖。

6.2 配置 CORS

然后在 config/initializers/cors.rb 中添加代码:

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins {true}
    resource '*',
        methods: [:get, :post, :delete, :patch, :options, :head],
        headers: :any,
        expose: ['*', 'Authorization'],
        max_age: 600
  end
end