我已经按照Rails 7指南中的描述建立了一个无表模型:
class ContactForm
include ActiveModel::Model
attr_accessor :name, :email, :message
validates :name, :email, :message, presence: true
end
我已经设置了一个操作来检查提交的内容是否有效,如果有效,则发送电子邮件:
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
当出现错误并再次呈现联系人模板时,@contact_form
似乎是一个空白的ContactForm
示例,例如@contact_form.errors.count
返回0,即使它在呈现命令之前在控制台中打印了正确的数字。
2条答案
按热度按时间1tu0hz3e1#
问题是由于尝试在表单提交后呈现带有 200 而不是 4xx 或 5xx 代码的页面。可以按如下方式添加422代码,并且建议在模型出现问题时使用该代码:
Rails 7附带了Turbo。它预期表单提交后会有一个303代码重定向,一个例外是当你需要渲染验证错误时。下面是它如何处理表单提交,以及为什么渲染命令本身不起作用,你可能只会得到上一页的某个版本:
Turbo Drive处理表单提交的方式类似于链接点击。主要区别在于表单提交可以使用HTTP POST方法发出有状态请求,而链接点击只会发出无状态HTTP GET请求。
在表单提交的有状态请求之后,Turbo Drive期望服务器返回HTTP 303重定向响应,然后它将遵循该响应并使用该响应来导航和更新页面,而无需重新加载。
此规则的例外情况是,当响应呈现为4xx或5xx状态代码时。这允许呈现表单验证错误,方法是让服务器响应“422不可处理的实体”,并在出现“500内部服务器错误”时,使服务器崩溃以显示“出错”屏幕。
Turbo不允许在200上进行常规渲染的原因是浏览器有一个内置的行为来处理POST访问时的重新加载,在重新加载时会显示一个Turbo无法复制的“你确定要再次提交此表单吗?”对话框。相反,Turbo会在提交表单时停留在当前的URL上,而不是将其更改为表单操作。因为重载将针对操作URL发出GET,而操作URL可能根本不存在。
2w2cym1i2#
上面的解决方案将完美地工作,但如果我们使用上面的Devise将增加大量的工作,因为Devise使用内部渲染,我们需要在任何地方自定义。
除了上述问题,另一个永久性的解决办法就在这里。
创建turbo控制器:
在
initializers/devise.rb
中使用以下代码:如果是另一个控制器,则可以继承此控制器。
Rails 7使用Turbo和激励框架来提高前端性能。
你需要安装涡轮和刺激。