我正在开发一个Rails 3应用程序,该应用程序需要在虚拟字段上运行验证,以查看记录是否已经存在。。。这是我的型号代码:
#mass-assignment
attr_accessible :first_name, :last_name, :dob, :gender
#validations
validates_presence_of :first_name, :last_name, :gender, :dob
validates :fullname, :uniqueness => { :scope => [:dob] }
def fullname
"#{first_name} #{last_name}"
end
我没有收到任何错误,它通过了验证。
我认为您不能用标准validates
做这样的事情。原因是,它通常是一个"简单"的sql查找唯一性。但要检查从您的方法返回的内容的唯一性,它必须:
- 获取您范围内的所有条目
- 对于每个,执行
fullname
方法 - 在测试唯一性时将每个结果添加到数组中
当数据集很小时,这很简单,但一旦你在你的范围内达到10公里以上的比赛,这只需要很长时间。
我个人会使用dob
范围在保存之前使用标准来完成这项工作
before_save :check_full_name_uniqueness
def check_full_name_uniqueness
query_id = id || 0
return !Patient.where("first_name = ? and last_name = ? and dob = ? and id != ?", first_name, last_name, dob, query_id).exists?
end
添加错误消息(返回之前):
errors.add(:fullname, 'Your error')
回到控制器,得到错误:
your_object.errors.each do |k, v| #k is the key of the hash, here fullname, and v the error message
#Do whatever you have to do
end