在model层里加入关于validates_presence_of、validates_numericality_of等验证,当客户端构造的对象通不过验证时,错误信息要反映到表单的放置error_messages的地方。
有以下几点要注意:
传递的实例变量
这里,要注意错误信息的传递,即如何从model层传递到view层。用实例变量(比如”@pet”),而不是pet,pet是传不过来的。
在view层,有
<% form_for :pet, @pet, :url => { :action => 'add' } do |f| %>
<%= f.error_messages %>(这一行也可以写作<%= error_messages_for :pet %>)
在controller层,则要
@pet = Pet.new(params[:pet])
如果我们写作pet= Pet.new(params[:pet]),错误信息就无法在view层呈现。
跳转
如果在controller中加入了保存失败的跳转处理,当验证失败后,系统直接转向了else的代码区,而没能把当前的模型对象出错信息显示到view层。
if @pet.save
redirect_to_message '保存成功'
#else
# redirect_to_message 'shibaila'
多个对象
在企业会员提交加盟申请时,表单里有两个对象:leagueapp 和 categories,前者是加盟信息,后者是经营类别。由于经营类别是从数据库动态加载的,所以,在数据验证失败后,leagueapp对象仍然有效,即@leagueapp仍然可以在view层显示。紧接着问题出现了,由于@categories只在页面提交时猜赋值的,而点击提交按钮后的request.post? 下的代码中,并没有@categories 的赋值情况,所以,view层无法显示最初正常显示的分类。
解决方法,当然很简单了,无论页面是否提交,每次均要加载@categories赋值的代码,确保页面提交失败时,view层可以正常显示分类那段代码。
也就是,把@categories = Category.find(:all) 放在 if request.post? … else … end 之外。
考虑到验证失败后,要保留用户刚才选中的分类,可以在提交的代码中记下选中的值,然后,在view层用js显示绑定
多对多的验证
一个加盟商可以有多个分类,两个表:leagueapps 和 scopes ,还有一个多对多的关系表leagueapps_scopes ,要注意在这两个model同时设置
has_and_belongs_to_many :leagueapps。
验证的语法,就和普通字段一样,在model / leagueapps.rb 下,用
validates_presence_of :addr, :message => '详细地址必填', :on => :create
validates_presence_of :scopes, :message => '经营项目至少选一个', :on => :create
尽管leagueapps表中没有scopes字段,ActiveRecord自动帮我们搞定啦。