Rails 6 如何将新建表单的提交校验逻辑从控制器迁移至模型
模型层校验实现方案
Rails Active Record 自带完整的校验生命周期钩子,你把校验逻辑写在模型里之后,不需要手动调用校验方法,常规的create/save/update操作会自动触发对应的校验规则。
第一步:在Submission模型中定义自定义校验
只需要在模型内通过validate注册自定义校验方法,加上on: :create限定仅在新建记录时触发,避免编辑已有提交时被误拦截:class Submission < ApplicationRecord belongs_to :user # 注册新建场景下的自定义校验 validate :check_duplicate_submission, on: :create private def check_duplicate_submission # 已存在同用户的提交记录时,给模型实例加错误 return unless user && user.submissions.exists? errors.add(:base, "你已提交过表单,无法重复创建提交") end end第二步:精简Controller层逻辑
删掉原来写在new动作里的重复提交判断逻辑,只需要在create动作里根据保存结果处理响应即可,校验失败时直接取模型生成的错误信息传给flash:class SubmissionsController < ApplicationController def new @submission = Submission.new end def create @submission = current_user.submissions.build(submission_params) if @submission.save redirect_to submissions_path, notice: "表单提交成功" else flash[:alert] = @submission.errors.full_messages.to_sentence render :new end end private def submission_params params.require(:submission).permit(:xxx, :yyy) # 替换为实际允许的表单字段 end end补充说明
如果你需要在非保存场景手动触发校验,可以直接调用实例的valid?方法,执行后所有注册的校验规则都会运行,错误信息会存在实例的errors属性中。常规业务流程不需要手动调用,Active Record会在写入数据库前自动执行所有校验,校验不通过时会直接阻断数据库写入,返回false。
注意:不要把flash提示的拼装逻辑写到模型里,模型层只负责校验规则和错误信息的挂载,视图/响应相关的逻辑还是留在Controller层处理,保持职责分离。
内容的提问来源于stack exchange,提问作者rafi
相关产品推荐
相关产品推荐

