表單的驗(yàn)證在ROR項(xiàng)目里是非常必要的手段桨菜,常規(guī)的表單驗(yàn)證有以下幾種方式:
1.model層面的validate逼裆;
2.controller層面的validate诗力;
3.view層面使用js進(jìn)行validate烙心;
上述幾種方式稿械,筆者在實(shí)際工作中都有使用选泻,下面分析一下這幾種方式的實(shí)現(xiàn)思路以及優(yōu)劣。
1.model層面:這是比較推薦的一種方式美莫,符合MVC框架的要求页眯,將驗(yàn)證的工作交給model,驗(yàn)證代碼的復(fù)用性會(huì)非常高厢呵,也最為可靠(這是相對(duì)前臺(tái)JS驗(yàn)證來(lái)說(shuō)窝撵,因?yàn)镴S驗(yàn)證可能因?yàn)闉g覽器對(duì)JS代碼兼容性的問(wèn)題或者禁用JS導(dǎo)致驗(yàn)證失敗)述吸。model層面除了默認(rèn)提供的驗(yàn)證字段的非空忿族、類型、不重復(fù)之外蝌矛,還可以支持代碼塊或者獨(dú)立的action道批,比如某個(gè)字段是用于存儲(chǔ)另一張表的多個(gè)id,中間使用英文的逗號(hào)隔開(kāi)入撒。那在寫(xiě)入這個(gè)字段的時(shí)候隆豹,需要驗(yàn)證用戶手填的id的合法性。此時(shí)在model中可以這樣實(shí)現(xiàn):
validate :validate_user_id
def validate_attention_people
errors.add(:user_ids, "用戶id輸入錯(cuò)誤") if xxx
end
errors是當(dāng)前實(shí)例化對(duì)象的一個(gè)屬性茅逮,可以使用errors.add()方法來(lái)增加報(bào)錯(cuò)信息璃赡,這個(gè)方法支持兩個(gè)參數(shù),第一個(gè)是返回錯(cuò)誤時(shí)献雅,作用在那個(gè)字段對(duì)應(yīng)的輸入框碉考。第二個(gè)參數(shù)就是報(bào)錯(cuò)的提示語(yǔ)。當(dāng)errors的內(nèi)容不為空時(shí)挺身,驗(yàn)證就不會(huì)被通過(guò)侯谁,數(shù)據(jù)不會(huì)被保存。
2.controller層面:一般不推薦在controller層面去驗(yàn)證然后返回錯(cuò)誤信息章钾,一方面不符合MVC的原則墙贱,代碼的復(fù)用性也會(huì)比較低(因?yàn)閷?duì)于同一個(gè)字段的驗(yàn)證,每個(gè)需要驗(yàn)證的action都需要寫(xiě)一遍)贱傀。如果的確需要用到惨撇,一般是這樣實(shí)現(xiàn)的:
render :text => "<script>alert('用戶id輸入有誤');history.back();</script>" and return if xxx
思路是直接調(diào)用js的history.back()強(qiáng)行返回到表單提交的頁(yè)面,然后彈出一個(gè)JS彈框描述報(bào)錯(cuò)的內(nèi)容府寒。
3.view層面:視圖層面的JS驗(yàn)證雖然不完全符合MVC的要求魁衙,但可以提供給用戶較為舒適的用戶體驗(yàn)报腔,實(shí)時(shí)反饋給用戶報(bào)錯(cuò)信息,而不需要不斷的刷新頁(yè)面后再返回纺棺。常見(jiàn)的方式是驗(yàn)證一些非空榄笙、字段類型、想要注冊(cè)的用戶名是否已占用等祷蝌。其中前兩個(gè)比較簡(jiǎn)單茅撞,直接可以在前臺(tái)驗(yàn)證。最后一個(gè)顯然需要使用ajax等方式進(jìn)行js提交去后臺(tái)驗(yàn)證巨朦,獲得結(jié)果后進(jìn)行判斷是否通過(guò)或者是阻止表單的提交米丘。想要實(shí)現(xiàn)這個(gè)過(guò)程,需要對(duì)ROR的action糊啡,路由拄查,jquery比較熟悉,從而完成一整套從前臺(tái)到后臺(tái)棚蓄,再返回前臺(tái)過(guò)程堕扶。實(shí)現(xiàn)的方式如下:
$(".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('以下關(guān)注人用戶名輸入錯(cuò)誤:' + data.join(";"))
return false
else
alert '發(fā)生錯(cuò)誤,請(qǐng)聯(lián)系公司IT梭依!'
return false
)
return false
此時(shí)后臺(tái)的action就比較簡(jiǎn)單了:
def check_attention_people
render :json => User.check_username(params[:attention_people_username_string]).to_json
end
前臺(tái)使用ajax進(jìn)行一次提交稍算,期待返回一個(gè)json類型的數(shù)據(jù),后臺(tái)接受到請(qǐng)求后役拴,對(duì)數(shù)據(jù)進(jìn)行查詢糊探,然后返回一個(gè)json格式的數(shù)據(jù),前臺(tái)再通過(guò)success的回調(diào)河闰,判斷是否驗(yàn)證通過(guò)或者阻止表單提過(guò)科平。
上述三種方式就是ROR項(xiàng)目中比較常見(jiàn)的驗(yàn)證方式,希望上述內(nèi)容能給各位讀者一些幫助姜性。