My Rails应用程序有多种形式。当Joe使用我的应用程序时,我希望每个表单都能为他提供关于每个字段输入的有效性的即时视觉反馈。一个字段检查他的电子邮件地址的格式 - 非常简单。但是另一个允许他将当前资源与许多其他资源相关联,并且适用复杂的业务规则。如果表单不完整或无效,我希望通过禁用“提交”按钮来阻止Joe前进。
我可以通过编写在浏览器中进行验证的JavaScript来复制我的Rails代码中出现的验证。但这闻起来很糟糕 - 任何时候业务规则发生变化,我都需要在两个地方用两种不同的语言和两组测试更新它们。
或者我可以为控制器添加一个名为'validate'的方法。它将接受AJAX请求中的表单数据,并返回一个响应,然后可以在Joe的表单中使用该响应来提供实时验证反馈。与“创建”操作不同,“验证”操作不会更改服务器的状态。 “验证”的唯一目的是提供验证响应。
困境在于我不喜欢在Rails中向RESTful控制器添加动作。但我更喜欢在两种不同的环境中复制验证代码的想法。
我注意到了this SO question,它触及了这个主题。但我对插件或技术不感兴趣。我也不认为这个问题必然是针对Rails的。我更感兴趣的是如何在Web应用程序中最好地处理这类问题。
我还注意到this SO question,它不包括维护RESTful架构的约束。
鉴于需要在Web应用程序中动态验证具有复杂业务规则的表单数据,以及维护类似REST的服务器体系结构的可取性,同时完成这两者的最干净,最易维护的方法是什么?
答案 0 :(得分:2)
我认为创建一个可以接受实体并确保它通过所有验证规则的验证器“处理资源”没有问题。
您可以使用全局验证器
执行此操作POST /validator
验证者必须识别传递的表示并执行适当的规则,或者您可以创建子资源,
POST/foo/validator
只要通过超媒体发现这些网址并将完整的验证表示作为请求的主体传递,我就看不到违反REST约束。
答案 1 :(得分:1)
我希望我理解正确,但您可以将javascript请求发送到同一个创建操作。例如:
def create
@data = DataObject.new(params[:data])
if request.xhr?
response = @data.valid? ? { :success => true } : { :errors => @data.errors }
render :json => response
return
end
# @data.save etc..
end
我实际上是在一个多步骤向导中使用这样的东西(一个页面形式,隐藏的CSS部分)。
答案 2 :(得分:0)
您不应在客户端(javascript)和服务器端复制验证逻辑。但是,添加验证资源还会增加维护工作量并降低服我喜欢在客户端进行基本验证(更好的用户体验)以及服务器端的数据一致性。
为什么不将模型附加验证元数据,然后生成用于验证的表单+ javascript。在最终提交时,您还可以根据模型在服务器端进行最终验证。
我确信Ruby可以使用一些通用的验证逻辑。我想也可以重用一些现有的验证框架。