Rails 在使用 Rails7+ Hotwire 开发项目时遇到关于错误处理的问题

theway · 2023年02月16日 · 最后由 theway 回复于 2023年02月17日 · 337 次阅读

学了 hotwire,做了个练手的小项目,遇见一个常见的表单验证:

def create
  if Tag.find_by(label: tag_params[:label])
    render :new, status: :unprocessable_entity
  else
    @tag = Tag.create(tag_params)
    respond_to do |format|
      format.turbo_stream
    end
  end
end

这段代码先查询是否有相同 label 的 Tag,如果没有再创建新 Tag 并 turbo_stream 更新到页面上。

如果表单没有通过验证,则返回 422。这一步是从教程上抄下来的。

我先是在该控制器视图文件夹下创建了一个空的 new.erb.html。提交错误表单时返回的结果直接将网页全覆盖了。

然后将此模板改名为 new.turbo_stream.html,因为这个文件内什么操作都没有做,所以提交错误表单没有任何反应,算是正常了。

我不知道自己目前的做法是否正确,使用 turbo 时,对于常见的表单验证不通过应该怎么处理?只能另建一个别名的 turbo_stream 而没有更优雅的方式了吗?

status: :unprocessable_entity 的作用是告诉 turbo 把返回的页面整个替换掉当前页面。正常来说 new.html.erb 是有内容的,才会用这个 status code。

假设成功和失败都用 turbo_stream 处理,这段代码我会这么写:

def create
  if @tag = Tag.create(tag_params) # Tag 模型的 validate 确保 label 唯一
    render turbo_stream: turbo_stream.append("tag_list", partial: "tag", locals { tag: @tag }) # 在 #tag_list 这个页面元素后面增加一个 tag
  else
    render turbo_stream: turbo_stream.replace("tag_form", partial: "form") # 替换 id 为 tag_form 的表单同时显示错误
  end
end

这里用了单行 turbo_stream 的返回形式,多行内容的话还是多个 turbo_stream 模版更优雅。

2 楼 已删除
Rei 回复

多谢解答,茅塞顿开~

需要 登录 后方可回复, 如果你还没有账号请 注册新账号