表单的验证在ROR项目里是非常必要的手段,常规的表单验证有以下几种方式:
1.model层面的validate;
2.controller层面的validate;
3.view层面使用js进行validate;
上述几种方式,笔者在实际工作中都有使用,下面分析一下这几种方式的实现思路以及优劣。
1.model层面:这是比较推荐的一种方式,符合MVC框架的要求,将验证的工作交给model,验证代码的复用性会非常高,也最为可靠(这是相对前台JS验证来说,因为JS验证可能因为浏览器对JS代码兼容性的问题或者禁用JS导致验证失败)。model层面除了默认提供的验证字段的非空、类型、不重复之外,还可以支持代码块或者独立的action,比如某个字段是用于存储另一张表的多个id,中间使用英文的逗号隔开。那在写入这个字段的时候,需要验证用户手填的id的合法性。此时在model中可以这样实现:
validate :validate_user_id
def validate_attention_people
errors.add(:user_ids, "用户id输入错误") if xxx
end
errors是当前实例化对象的一个属性,可以使用errors.add()方法来增加报错信息,这个方法支持两个参数,第一个是返回错误时,作用在那个字段对应的输入框。第二个参数就是报错的提示语。当errors的内容不为空时,验证就不会被通过,数据不会被保存。
2.controller层面:一般不推荐在controller层面去验证然后返回错误信息,一方面不符合MVC的原则,代码的复用性也会比较低(因为对于同一个字段的验证,每个需要验证的action都需要写一遍)。如果的确需要用到,一般是这样实现的:
render :text => "<script>alert('用户id输入有误');history.back();</script>" and return if xxx
思路是直接调用js的history.back()强行返回到表单提交的页面,然后弹出一个JS弹框描述报错的内容。
3.view层面:视图层面的JS验证虽然不完全符合MVC的要求,但可以提供给用户较为舒适的用户体验,实时反馈给用户报错信息,而不需要不断的刷新页面后再返回。常见的方式是验证一些非空、字段类型、想要注册的用户名是否已占用等。其中前两个比较简单,直接可以在前台验证。最后一个显然需要使用ajax等方式进行js提交去后台验证,获得结果后进行判断是否通过或者是阻止表单的提交。想要实现这个过程,需要对ROR的action,路由,jquery比较熟悉,从而完成一整套从前台到后台,再返回前台过程。实现的方式如下:
$(".btn-save-purchase-application").click ->
if $("#ams_purchase_application_attention_people").val() != ''
attention_people_username_string = $("#ams_purchase_application_attention_people").val()
$.ajax(
url: '/ams/purchase_applications/check_attention_people',
dataType: 'json',
type: 'put',
data: {"attention_people_username_string": attention_people_username_string},
success: (data, textStatus) ->
if textStatus == 'success'
if data.length == 0
$("#ams_purchase_application_form").submit()
return false
else
alert('以下关注人用户名输入错误:' + data.join(";"))
return false
else
alert '发生错误,请联系公司IT!'
return false
)
return false
此时后台的action就比较简单了:
def check_attention_people
render :json => User.check_username(params[:attention_people_username_string]).to_json
end
前台使用ajax进行一次提交,期待返回一个json类型的数据,后台接受到请求后,对数据进行查询,然后返回一个json格式的数据,前台再通过success的回调,判断是否验证通过或者阻止表单提过。
上述三种方式就是ROR项目中比较常见的验证方式,希望上述内容能给各位读者一些帮助。