在 Rails 7 中提交表单后渲染视图无法正常工作

Dav*_*veR 6 ruby-on-rails

我已经按照 Rails 7 指南中的描述设置了一个无表模型:

class ContactForm
    include ActiveModel::Model
  
    attr_accessor :name, :email, :message
    validates :name, :email, :message, presence: true

end
Run Code Online (Sandbox Code Playgroud)

我已经设置了一个操作来检查提交的内容是否有效并发送电子邮件(如果有效):

  def contact_process 
    @contact_form = ContactForm.new(contact_form_params)
    
    if @contact_form.valid?
      UserMailer.with(@contact_form).contact_form.deliver_later 
      redirect_to contact_path
    else  
      render :contact
    end 
  end 
Run Code Online (Sandbox Code Playgroud)

当出现错误并且再次呈现联系人模板时,@contact_form它似乎是一个空白ContactForm实例,例如@contact_form.errors.count返回 0,即使它在渲染命令之前在控制台中打印了正确的数字。

Dav*_*veR 14

该问题是由于尝试在表单提交后使用200而不是4xx5xx代码呈现页面。可以按如下方式添加 422 代码,并在模型出现问题时建议使用:

\n
render 'contact', status: :unprocessable_entity\n
Run Code Online (Sandbox Code Playgroud)\n

Rails 7 附带 Turbo。它期望表单提交后跟随 303 代码重定向,一个例外是当您需要呈现验证错误时。以下是它处理表单提交的方式,以及为什么渲染命令本身不起作用,并且您可能只会获得上一页的某些版本:

\n
\n

Turbo Drive 以类似于链接\n单击的方式处理表单提交。主要区别在于,表单提交可以使用 HTTP POST 方法发出有状态请求,而链接单击只能发出无状态 HTTP GET 请求。

\n

在表单提交发出有状态请求后,Turbo Drive 预计\n服务器返回 HTTP 303 重定向响应,然后\n它将遵循该响应并使用该响应来导航和更新页面,而无需重新加载。

\n

此规则的例外情况是,响应使用 4xx 或 5xx 状态代码呈现。这允许通过让服务器响应 422 无法处理的实体来呈现表单验证错误,并且损坏的服务器可以在 500 内部服务器错误上显示 \xe2\x80\x9cSomething Went Wrong\xe2\x80\x9d 屏幕。

\n

Turbo 不允许\xe2\x80\x99 不允许在 200 上进行常规渲染的原因是\n浏览器具有处理 POST 上重新加载的内置行为\n访问时显示 \xe2\x80\x9c您确定要提交此表单吗\nagain?\xe2\x80\x9d Turbo 可以\xe2\x80\x99t 复制的对话。相反,Turbo 将在尝试呈现的表单提交时保留\n当前 URL,而不\n将其更改为表单操作,因为重新加载将针对该操作 URL 发出\nGET,而该操作 URL 可能根本不存在。

\n
\n