Rails-start

2020-09-20  本文已影响0人  littleyu

如何进行架构设计

难点不在于架构设计的好不好,而在于细节是否做得妥当,或者叫做你的架构是否基于最佳实践。

依据

用户需求

团队配置

技术成熟度

什么是前后端分离

这里说的前端和后端是指前端代码和后端代码,不指人。
不分离:传统的后端工程师从数据库、Redis读取数据渲染到 HTML 中,HTML 需要引用 js、css ,但是现代前端代码代码都是打包生成的(style.xxx.css、main.xxx.js),所以无法在 HTML 中提前引用这些 js、css,所以只能用 Rails(插件 webpacker) 读取 webpack 的内容,再反向写到 HTML 中。
分离:前端自己负责 HTML,自己搭建静态服务器给用户访问,如:Ngnix 或 Node等等,好处是 HTML 可以直接用 webpack 的插件,直接把打包后生成的文件写到 HTML 中,数据只通过 AJAX 获取。

注意前后端代码不一定要交给两个人写,可以由一个人写

用户需求

视觉稿

用例图

用例图释义:把使子全部画出来

表设计

有哪些表?

每个表有哪些属性

users 表

从需求出发

结论

开始实现

步骤

约定

创建数据库 bin/rails db:create

创建 User 表和 Model

bin/rails db:migrate
bin/rails g model User email:string password_digest:string

使用控制台增删改查

bin/rails console
# 创建用户
> u = User.new
> u.email = '1.qq.com'
> u.password_digest = 'xxxxxx'
> u.save
# 查
User.all # 全部
User.all[0] # 第一个 或 User.first、User.second(用英文即可)

不用写任何代码,为什么就可以进行增删改查呢?这才是一个成熟的框架应该内置好的。

上述操作有个问题,我们不能直接赋值 password_digest

再次创建

bin/rails console
# 创建用户
> u = User.new
> u.email = '2.qq.com'
> u.password = 'xxxxxx'
> u.password_confirmation = 'xxxxxx'
> u.save

使用 http 请求来创建用户

首先在 routes 里添加

get '/users', to: 'users#index'
get '/users/:id', to: 'users#show'
post '/users', to: 'users#create'
delete '/users/:id', to: 'users#destroy'
patch '/users/:id', to: 'users#update'

这五个增删改查几乎是每个表都要写,既然这么麻烦,于是 rails 就提供了另一个方法,等价于写了上面五句话

resources :users

使用 bin/rails routes 即可查看所有 routes 得以验证

创建 controller

bin/rails g controller users

然后在 controller 定义一个 create 方法

class UsersController < ApplicationController
  def create
    user = User.new
    user.email = params[:email]
    user.password = params[:password]
    user.password_confirmation = params[:password_confirmation]
    user.save
  end
end

但是测试时发现没有传 password_confirmation 竟然也能成功保存,所以我们需要加上非空校验

在 user.rb 中加入

class User < ApplicationRecord
  has_secure_password
  validates_presence_of :email
  validates_presence_of :password, :password_confirmation, on: [:create] # 只在创建时校验
end

并加上返回响应

class UsersController < ApplicationController
  def create
    user = User.new
    user.email = params[:email]
    user.password = params[:password]
    user.password_confirmation = params[:password_confirmation]
    if user.save
      render json: user, status: 200
    else
      render json: user.errors, status: 400
    end
  end
end

当我们什么都没传时,发现 password 重复报错了两遍,可能是 has_secure_password 也做了校验,所以移除我们自己的

class User < ApplicationRecord
  has_secure_password
  validates_presence_of :email
  validates_uniqueness_of :email
  validates_presence_of :password_confirmation, on: [:create] # 只在创建时校验
end

再加上更完善的校验

class User < ApplicationRecord
  has_secure_password
  validates_presence_of :email
  validates_presence_of :password_confirmation, on: [:create]

  validates_format_of :email, with: /.+@.+/
  validates_length_of :password, minimum: 6, on: [:create]
end

校验国际化

# config/initializers/locale.rb

# Where the I18n library should search for translation files
I18n.load_path += Dir[Rails.root.join('lib', 'locale', '*.{rb,yml}')]

# Permitted locales available for the application
I18n.available_locales = [:en, 'zh-CN']

# Set default locale to something other than :en
I18n.default_locale = 'zh-CN'
zh-CN:
  activerecord:
    errors:
      models:
        user:
          attributes:
            password:
              blank: 密码不能为空
              too_short: 密码不能少于 %{count} 位
            email:
              blank: 邮箱不能为空
              invalid: 邮箱格式不合法
            password_confirmation:
              blank: 确认密码不能为空

额外,优化一下上面的这部分代码

class UsersController < ApplicationController
  def create
    user = User.new
    user.email = params[:email]
    user.password = params[:password]
    user.password_confirmation = params[:password_confirmation]
    if user.save
      render json: { resource: user }, status: 200
    else
      render json: { errors: user.errors }, status: 400
    end
  end
end

第一步

class UsersController < ApplicationController
  def create
    user = User.new({ email: params[:email], password: params[:password], password_confirmation: params[:password_confirmation] })
    if user.save
      render json: { resource: user }, status: 200
    else
      render json: { errors: user.errors }, status: 400
    end
  end
end

第二步使用 permit 方法

class UsersController < ApplicationController
  def create
    user = User.new params.permit(:email, :password, :password_confirmation)
    if user.save
      render json: { resource: user }, status: 200
    else
      render json: { errors: user.errors }, status: 400
    end
  end
end

第三步

class UsersController < ApplicationController
  def create
    user = User.new create_params
    user.save
    render_resource user
  end

  def create_params
    params.permit(:email, :password, :password_confirmation)
  end

  def render_resource(resource)
    if resource.valid?
      render json: {resource: resource}, status: 200
    else
      render json: {errors: resource.errors}, status: 400
    end
  end
end

第四步,使用 create 方法,等价于 先 new 再 save

class UsersController < ApplicationController
  def create
    user = User.create create_params
    render_resource user
  end

  def create_params
    params.permit(:email, :password, :password_confirmation)
  end
end
  # render_resource 方法已提升到 ApplicationController 中

第五步,很明显 user 声明了直接使用

class UsersController < ApplicationController
  def create
    render_resource User.create create_params
  end

  def create_params
    params.permit(:email, :password, :password_confirmation)
  end
end

发送邮件

class UserMailer < ApplicationMailer
  def welcome_email(user)
    @user = user
    @url = 'https://www.baidu.com'
    mail(to: @user.email, subject: 'Welcome to My Awesome Site')
  end
end
class ApplicationMailer < ActionMailer::Base
  default from: '529743595@qq.com'
  layout 'mailer'
end

  <p>
    <%= @user.email %> 您好,
  </p>
  <p>
    欢迎来到 Morney,情记一笔把!
  </p>

# config.action_mailer.raise_delivery_errors = false
  #
  # config.action_mailer.perform_caching = false
  config.action_mailer.delivery = :smtp
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.perform_caching = false
  config.action_mailer.smtp_settings = {
    address: ENV['smtp_domain'],
    port: ENV['smtp_port'],
    domain: ENV['smtp_domain'],
    user_name: ENV['smtp_username'],
    password: ENV['smtp_password'],
    authentication: ENV['smtp_authentication'],
    enable_starttls_auto: ENV['smtp_enable_starttls_auto'],
  }
  config.action_mailer.preview_path = "#{Rails.root}/spec/mailers/previews"
gem 'dotenv-rails'
Bundler.require(*Rails.groups)
Dotenv::Railtie.load
export smtp_username=''
export smtp_password=''
export smtp_domain='smtp.qq.com'
export smtp_port='587'
export smtp_authentication='plain'
export smtp_enable_starttls_auto=true

export mailer_sender=''
export smtp_username='xxxxx'
export smtp_password='xxxxxx'
class User < ApplicationRecord
  has_secure_password
  validates_presence_of :email
  validates_uniqueness_of :email
  validates_presence_of :password_confirmation, on: [:create]

  validates_format_of :email, with: /.+@.+/, if: :email
  validates_length_of :password, minimum: 6, on: [:create], if: :password

  after_create :send_welcome_email
  def send_welcome_email
    UserMailer.welcome_email(self).deliver_now
  end
end

上一篇 下一篇

猜你喜欢

热点阅读