Validation (转)

本文介绍Rails框架中的模型验证方法,包括11种常见的验证辅助方法及其使用场景,如验证唯一性、验证格式等。
15.4 Validation

1、validates_acceptance_of 确认checkbox是否被标记
2、validates_associated 在关联的对象上完成确认。
3、validates_confirmation_of 确认字段和它的值有同样内容
4、validates_each 使用一个块来确认一或多个属性
5、validates_exclusion_of 确认属性不在一组值中。
6、validates_format_of 在一个模式上确认属性。
7、validates_inclusion_of 确认属性是否属于一个值集。
8、validates_length_of 确认属性值的长度。
9、validates_numericality_of 确认那个属性是有效的数字
10、validates_presence_of 确认属性不为空。
11、validates_uniqueness_of 确认属性是唯一的。

“活动记录”可以确认一个“模型”对象的内容。这个确认在一个对象被保存时可以自动地完成。你也可以编程请求一个“模型”的当前状态的确认。

就像我们在上一章提到的,“活动记录”能够区别出数据库内与现有行相应的“模型”还是没有现有行与之对应的“模型”。后者被称为新记录(new_record?()方法将为它们返回true)。当你调用save()方法时,“活动记录”将为新记录完成一个SQL 插入操作并对现有的那个进行更新。

这种区别是“活动记录”的确认工作流的反射—你可以指定在所有保存操作上完成的确认,以及只用于创建或更新上完成的确认。

在低层你通过实现validate( ), validate_on_create( ), 和 validate_on_update( )这些方法的一个或多个来指定确认。validate()方法在每个保存操作中被调用。后两个则依赖于记录是否是新的,或者它先前是否从数据库中读取过来调用。

除了调用valid?()保存“模型”对象到数据外,你也可以在任何时候运行确认。这个调用与调用save()来保存的两个确认方法是一样的。
class User < ActiveRecord::Base
def validate
unless name && name =~ /^w+$/
errors.add(:name, "is missing or invalid")
end
end
def validate_on_create
if self.find_by_name(name)
errors.add(:name, "is already being used")
end
end
end
当一个确认方法发现问题时,它使用errors.add()方法添加一个信息给这个“模型”对象的错误列表。第一个参数是出错属性的名字,第二个参数是错误消息。如果你需要添加一个用于整个“模型”对象的错误消息,使用add_to_base()方法代替。(注意,这个代码使用了支持方法blank?(),它在它的被调为nil或是个空字符串时返回true。)
def validate
if name.blank? && email.blank?
errors.add_to_base("You must specify a name or an email address")
end
end
像我们353页看到的,Rails“视图”在显示表单给最终用户时可以使用错误列表—有错误的字段将被自动高亮度地显示,并且用错误列表添加一个漂亮的方框在顶部。
你可以编程为一个特定属性使用errors.on(:name)(别名为errors[:name])来获得错误,并且你可以用errors.clear()清除整个错误列表。如果你查阅ActiveRecord::Errors文档,你会发现有很多其它方法。大多数方法可由高级的确认帮助方法来代替。
Validation Helpers
有些确认是平常:这个属性必须不能为空,其它属性必须在18和65之间等等。“活动记录”有一套标准的帮助方法来添加这些确认给你的“模型”。每个都是类级别方法,所有名字都以validates_开头。每个方法接受可选的属性名字列表,它是由配置选项的哈希表提供给确认的。

例如,我们可以这样写先前确认
class User < ActiveRecord::Base
validates_format_of :name,
:with => /^w+$/,
:message => "is missing or invalid"
validates_uniqueness_of :name,
:on => :create,
:message => "is already being used"
end
大多数validates_methods接受:on和:message选项。:on选项确定何时应用确认并接受:save(缺省的),:create,或:update中的一个。:message参数可以用生成错误消息覆写它。
确认失败时,帮助方法添加一个error对象给“活动记录”“模型”对象。这将被关联到被确认的字段。在确认之后,你可以查看“模型”对象的errors属性来访问错误列表。当“活动记录”被用做Rails应用程序一部分时,这个检查通常由两个步骤完成:
1、“控制器”试图保存一个“活动记录”对象,但因为确认的原因保存失败了 (返回false)。 “控制器”将重新显示包含错误数据的表单。
2、“视图模板”使用error_messages_for()方法来显示“模型”对象的错误列表,并且用户有机会来修正字段。
我们在17.8节讨论表单与“模型”的交互。
这儿是你可以用在“模型”对象内的确认帮助方法的清单:

1、validates_acceptance_of 确认checkbox是否被标记。
validates_acceptance_of attr... [ options... ]
许多表单有checkbox,用户必须选择以便接受一些条款或条件。这个确认简单地检验这个box已经确认被标记,这个属性值是个字符串。属性本身并不被保存在数据库内(如果你希望明确地记录确认的话,没有什么东西会阻止你这样做)。
class Order < ActiveRecord::Base
validates_acceptance_of :terms,
:message => "Please accept the terms to proceed"
end
选项:
:message text,缺省是“must be accepted.”。
:on :save,:create 或者:update

2、validates_associated 在关联的对象上完成确认。
validates_associated name... [ options... ]
在给定的属性上完成确认,它被假设为是“活动记录模型”。对每个与属性关联的确认失败的话,一个单独的消息将被添加到那个属性的错误列表中(也就是说,个别的细节原因而出现的失败,将不会写到“模型”的错误列表中)。
小心不要包含一个validates_associated()调用在彼此引用的“模型”中:第一个将会试图确认第二个,它依次将确认第一个等等,直接你堆栈溢出。
class Order < ActiveRecord::Base
has_many :line_items
belongs_to :user
validates_associated :line_items,
:message => "are messed up"
validates_associated :user
end
选项:
:message text ,缺省是 “is invalid.”
:on :save,:create 或者:update

3、validates_confirmation_of 确认字段和它的值有同样内容。
validates_confirmation_of attr... [ options... ]

很多表单要求用户输入同一信息两次,第二次拷贝“动作”被做为与第一次是否匹配的确认。如果你使用命名约定,即第二字段的名字附有_confirmation,你可以使用validates_confirmation_of()来检查两个字段是否有同样的值。第二个字段不需要被存储到数据库中。
例如,一个“视图”可能包含
<%= password_field "user", "password" %><br />
<%= password_field "user", "password_confirmation" %><br />
在User“模型”中,你可以用一个确认来检验两个口令。
class User < ActiveRecord::Base
validates_confirmation_of :password
end
选项:
:message text 缺省是“doesn’t match confirmation.”
:on :save, :create, 或 :update

4、validates_each 使用一个块来确认一或多个属性。
validates_each attr... [ options... ] { |model, attr, value| ... }
为每个属性调用块(如果:allow_nil为true,则跳过是nil的属性)。传递属性的名字,属性的值到被确认的“模型”内。如下面例子显示的,如果一个确认失败,块应该被添加给“模型”的错误列表
class User < ActiveRecord::Base
validates_each :name, :email do |model, attr, value|
if value =~ /groucho|harpo|chico/i
model.errors.add(attr, "You can't be serious, #{value}")
end
end
end
选项:
:allow_nil boolean 如果 :allow_nil 为 true,带有值nil的属性将不被传递给块而是被跳过。
:on :save, :create, 或 :update

5、validates_exclusion_of 确认属性不在一组值中。
validates_exclusion_of attr..., :in => enum [ options... ]
确认属性没有出现在枚举中(任何对象都支持include?()断言)。
class User < ActiveRecord::Base
validates_exclusion_of :genre,
:in => %w{ polka twostep foxtrot },
:message => "no wild music allowed"
validates_exclusion_of :age,
:in => 13..19,
:message => "cannot be a teenager"
end
选项:
:allow_nil 如果属性为nil,并且:allow_nil选项为true。则枚举不被检查。
:in (或 :within) enumerable 一个可枚举对象。
:message text 缺省值是 “is not included in the list.”
:on :save, :create, 或 :update

6、validates_format_of 在一个模式上确认属性。
validates_format_of attr..., :with => regexp [ options... ]
通过与正则表达式匹配它的值来确认每个字段。

class User < ActiveRecord::Base
validates_format_of :length, :with => /^d+(in|cm)/
end
选项:
:message text 缺省值 “is invalid.”
:on :save, :create, or :update
:with 用于确认属性的正则表达式。

7、validates_inclusion_of 确认属性是否属于一个值集。
validates_inclusion_of attr..., :in => enum [ options... ]
确认每个属性的值是否出现在枚举中(任何对象都支持include?()断言)。
class User < ActiveRecord::Base
validates_inclusion_of :gender,
:in => %w{ male female },
:message => "should be 'male' or 'female'"
validates_inclusion_of :age,
:in => 0..130,
:message => "should be between 0 and 130"
end
选项:
:allow_nil 如果属性为nul并且:allow_nil选项为true,则不检查枚举值。
:in (或 :within) enumerable 一个可枚举的对象。
:message text 缺省值是 “is not included in the list.”
:on :save, :create, 或 :update

8、validates_length_of 确认属性值的长度。
validates_length_of attr..., [ options... ]
遵循一些约束确认每个属性的值的长度:至少要给出一个长度,至多给出一个长度,在两个长度之间,或者明确地给出一个长度。而不能只有单个:message选项,这个确认器允许为不同的确认失败分离消息,只要:message还可以使用。在所有选项中,长度不能负数。
class User < ActiveRecord::Base
validates_length_of :name, :maximum => 50
validates_length_of :password, :in => 6..20
validates_length_of :address, :minimum => 10,
:message => "seems too short"
end
选项(用于validates_length_of):
:in (或 :within) range 值的长度必须在一个范围内。
:is integer 值必须是整数的字符长度。
:minimum integer 值不能小于此整数。
:maximum integer 值不能大于此整数。
:message text 依赖于完成测试的缺省信息。消息可以包含一个将被maximun,minimum,或确定长度代替的%d序列。
:on :save, :create, 或 :update
:too_long text 使用:maximum时的:message同义词。
:too_short text使用:minimum时的:message同义词。
:wrong_length text使用:is 时的:message同义词。

9、validates_numericality_of 确认那个属性是有效的数字。
validates_numericality_of attr... [ options... ]
确认每个属性是个有效数字。在:only_integer选项中,属性必须由可选的符号后跟随一个或多个数字。在选项中(或者如果选项不是true),可由Ruby Float()方法允许的任何浮点数都被接受。
class User < ActiveRecord::Base
validates_numericality_of :height_in_meters
validates_numericality_of :age, :only_integer => true
end
选项:
:message text 缺省是 “is not a number.”
:on :save, :create, 或 :update
:only_integer 如果为 true,则属性必须是包含一个可选的符号后跟随数字的字符串。
10、validates_presence_of 确认属性不为空。
validates_presence_of attr... [ options... ]
确认每个属性即不为nil也不为空。
class User < ActiveRecord::Base
validates_presence_of :name, :address
end
选项:
:message text 缺省是 “can’t be empty.”
:on :save, :create, 或 :update

11、validates_uniqueness_of 确认属性是唯一的。
validates_uniqueness_of attr... [ options... ]
对于每个属性,确认数据库内的其它行当前没有与给定列同样的值。当“模型”对象来自于一个现有数据库的行时,当完成检查时那个行被忽略。选项:scope参数可以被用于过滤当前记录内:scope列内被测试的,有同样值的行。
这个代码确保用户名字在数据库中唯一的。
class User < ActiveRecord::Base
validates_uniqueness_of :name
end
这个代码确保用户的名字在一个组内唯一的。
class User < ActiveRecord::Base
validates_uniqueness_of :name, :scope => "group_id"
end
选项:
:message text 缺省是 “has already been taken.”
:on :save, :create, 或 :update
:scope attr Limits the check to rows having the same value in the column as the row being checked.
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值