ruby-on-rails - Rails 重定向或渲染以显示错误
问题描述
当用户对资源发出无效的创建请求时,我想将它们发送回表单并向他们显示错误。据我所知,调用render "new"
是标准的方法。
这对我来说似乎是个坏主意,因为创建请求已将用户带到 /resources,而我的“新”表单位于 /resources/new。如果我使用render "new"
,地址栏中的 URL 将不会反映用户看到的内容。如果他们在那里发出 GET 请求,他们最终会出现在不同的页面上。
我以为我可以通过使用来解决这个问题redirect_to new_[resource]_path
,但如果我这样做,我将无法访问表单数据和错误。当然,这不是一个罕见的问题。有没有更好的方法来处理它?
我对编辑/更新和其他表单/提交操作对有同样的问题。
解决方案
TL;博士:
class ResourcesController < ApplicationController
def new
@resource = Resource.new(resource_params)
if resource_params.present?
@resource.validate
end
end
def create
@resource = Resource.new(resource_params)
if @resource.save
redirect_to @resource, notice: 'Resource has been created'
else
redirect_to new_resource_url(resource: resource_params)
end
end
private
def resource_params
params.fetch(:resource, {}).permit(...)
end
end
在我早期的初学者日子里,我自己也问过这个问题,为什么 Rails 脚手架生成器def create
会在保存失败时生成操作render :new
,而不是像上面那样重定向到正确的 URL,这会使用户感到困惑,因为他们的 URL 会从更改/resources/new
为/resources
即使他们仍然会在页面上看到完全相同的资源表单,因此他们将无法重新加载页面或复制此/resources
URL(例如,如果他们想将此 URL 共享给其他人),因为他们应该共享此/resources
URL,其他人将在页面上看到资源列表,而不是原始用户期望从复制的 URL 中看到的内容:这是表单页面。
用户提交表单后,他们在地址栏上看到的 URL 应该已经变成了POST http://localhost:3000/resources
,而不仅仅是简单的http://localhost:3000/resources
. 浏览器隐藏了正在使用的 HTTP 方法,这就是为什么这会导致它们可能的混淆,/resources
有时似乎两者兼而有之:表单页面,有时是资源列表页面。但是,说到用户体验,每当有人在浏览器的 URL 地址栏中输入或粘贴某些内容时,总是自动暗示在进行GET
请求。GET
因此,浏览器开发人员只需简单地向用户隐藏 HTTP 方法(即特别是)以免混淆他们是有意义的。
从我上面的回答中,我以前只使用过一次这样的东西(因为有一个特定的操作要求我不要从推荐人表单页面更改 URL)。但是,我通常render :new
而不是redirect_to new_resources_url
,仅仅是因为:
a
redirect_to new_resource_url(resource_params)
将花费两倍的时间和数据传输比简单的呈现:new
。为什么?因为无论如何您都使用完全相同的参数重定向(打开一个新请求)。试想一下,如果您的表单页面很大,并且有很多输入字段。并且 URL 的长度是有限制的,如果您的表单很大且文本字段很长,则不能保证有效。看到这个
更新:
正如您所说,为什么不只是在提交表单时POST /resources/new
代替,对吧?POST /resources
这将解决redirect_to new_resource_url(resource_params)
我上面显示的问题,因为 form-submit 之后的 URL 将是相同的,您可以简单地render :new
, 然后。我实际上同意这一点,而且我在很久以前也使用过类似的东西。我不使用它的主要原因是它不符合 REST 标准。也就是说:POST /resources/new
意味着您正在“内部”resources/new
位置创建一个 Resource 对象,这意味着通过 REST,在提交表单后,我将并且应该能够通过执行类似的操作来访问这个新创建的资源GET /resources/new/the_newly_created_record
,除了.. . 你不能。
但是您仍然可以使用POST /resources/new
,尽管我不建议在像您这样的普通 Rails 应用程序上使用它,但在基于 API 的 Rails 应用程序上严格不鼓励它。
推荐阅读
- r - 设置当前用户的路径
- php - Laravel - 如何调用模型类助手然后在视图中显示结果
- excel - 使 LastRow 成为整数的下标超出范围错误
- python - 如何只保留包含特定值的连续数字
- azure-devops - 如何在 MAC 中配置 VSTS-agent?
- c++ - 指针转换是否保持对齐属性?
- linux - Linux命令验证每台机器连接的是哪个交换机
- playframework - 玩 2.3 WS keystore 配置
- mongodb - 如何在mongodb中查找与外国文档相同的集合
- reactjs - react-dnd:添加 DragSource 会破坏本机输入的默认放置功能