Active Record Validations 2 Validation Helpers 校验辅助方法_Ruby_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > Ruby > Active Record Validations 2 Validation Helpers 校验辅助方法

Active Record Validations 2 Validation Helpers 校验辅助方法

 2014/7/22 20:17:50  jiajie0531  程序员俱乐部  我要评论(0)
  • 摘要:version:Rails4.12ValidationHelpers校验辅助方法ActiveRecord提供了许多预定义的校验辅助方法(helpers),你可以直接在你的类定义中使用.这些辅助方法提供了一般性校验的规则.每一次校验失败时,一个错误信息被增加到对象的errors集合,这个信息被关联到已被校验的属性.每一个helper接受属性名称的任意数量,因此对于单独行的代码,你可以对几个属性增加相同类型的校验.他们都接受属性:on和:message,当校验被运行时定义上述属性,当校验失败时
  • 标签:方法 helpers
version: Rails 4.1

2 Validation Helpers 校验辅助方法

Active Record 提供了许多预定义的校验辅助方法(helpers), 你可以直接在你的类定义中使用. 这些辅助方法提供了一般性校验的规则. 每一次校验失败时, 一个错误信息被增加到对象的 errors 集合, 这个信息被关联到已被校验的属性. ? 每一个helper 接受属性名称的任意数量, 因此对于单独行的代码, 你可以对几个属性增加相同类型的校验. ? 他们都接受属性 :on 和 :message, 当校验被运行时定义上述属性, 当校验失败时, 把相应的错误信息增加到 errors 集合里. :on 属性获取的值是 :create 或者 :update. 对于每一个校验的 helpers 有默认的错误信息. 当 :message 属性没有被声明时, 这些信息会被使用. 让我们来分别看一下每一个可用的 helpers. ?

2.1class="Apple-converted-space">?monospace; font-size: 12px; line-height: 16px; font-style: normal; background-color: inherit;">acceptance 接受

这个方法校验的是, 当一个 form 被提交的时候, 用户界面上的 checkbox 要被勾上. 这通常用于, 当用户同意你的应用服务协议的时候, 确认读到的文字, 或者类似的概念. 这个校验对于web应用是很著名的, 这个 'acceptance' 不需要被记录到你的数据库里(如果你没有为它设置字段, helper会创建一个虚拟的属性). class?Person < ActiveRecord::Base ??validates?:terms_of_service, acceptance:?true end

这个helper 默认的错误信息是 "must be accepted".

?

它能收到一个 :accept 属性, 来决定所想要的接受值. 默认是"1", 更改起来也容易.

class?Person < ActiveRecord::Base ??validates?:terms_of_service, acceptance: { accept:?'yes'?} end

2.2?validates_associated 关联校验

你应该使用这个 helper, 当你的模型和其他的模型有关联的时候, 他们也需要被校验. 当你尝试去保存你的对象时, valid? 将会被紧接着调用, 涉及到所关联的对象. class?Library < ActiveRecord::Base ??has_many?:books ??validates_associated?:books end

这个校验将会对于所有的关联类型都会起作用.

?

warning: 不要对于你的关联对象两端都使用 validates_associated. 他们将会陷入互相调用的无限循环.

?

对于 validates_associated 的默认错误信息是 "is invalid". 注意, 每一个被关联的对象都包含各自的 errors 集合, errors 不会在调用模型时冒出来.

?

2.3?confirmation 确认

你应该使用这个 helper, 当你有两个文本字段需要接受相同的内容时. 例如, 你可能想要确认一个 email 地址或者一个密码. 这个校验会创建一个虚拟的属性, 它的名字就是需要被确认字段的名字, 只是后面要加上"_confirmation". class?Person < ActiveRecord::Base ??validates?:email, confirmation:?true end

在你的视图模板中, 你可以这样使用:

<%=?text_field?:person,?:email?%> <%=?text_field?:person,?:email_confirmation?%>

这个校验只有当 email_confirmation 不为 nil时, 才会被执行. 为了声明必须要确认, 确定要增加一个对于确认特性的 presence 检查(我们将会在后面详细了解 presence).

class?Person < ActiveRecord::Base ??validates?:email, confirmation:?true ??validates?:email_confirmation, presence:?true end

对于这个 helper 的默认错误信息是 "doesn't match confirmation".

?

2.4?exclusion 不包括

这个 helper 校验的是, 属性的值没有被包括在所提供的集合中. 事实上, 这个集合能够是任何可列举的对象. class?Account < ActiveRecord::Base ??validates?:subdomain, exclusion: {?in: %w(www us ca jp), ????message:?"%{value} is reserved."?} end

这个 exclusion helper 有一个属性 :in, 接收一些值的集合, 这些值将不会被校验的特性所接收. :in 属性有一个别名叫作 :within, 你可以用来表示相同的作用目的, 如果你乐意这样做的话. 这个例子使用的 :message 属性是用来显示, 你如何能够包括特性的值.

?

默认的错误信息是 "is reserved".

?

2.5?format 格式

这个 helper 校验特性的值, 是通过测试他们是否匹配所给予的正则表达式, 详细的声明在 :with 属性. class?Product < ActiveRecord::Base ??validates?:legacy_code, format: { with: /\A[a-zA-Z]+\z/, ????message:?"only allows letters"?} end

默认的错误信息是 "is invalid".

?

2.6?inclusion 包含

这个 helper 校验的是, 属性的值要被包含在被给予的集合内. 事实上, 这个集合能够是任何可列举的对象. class?Coffee < ActiveRecord::Base ??validates?:size, inclusion: {?in: %w(small medium large), ????message:?"%{value} is not a valid size"?} end

这个 inclusion helper 有一个属性 :in, 接收的一些值的集合是被接受的.

:in 属性有一个别名叫作 :within, 你可以用来表示相同的作用目的, 如果你乐意这样做的话. ?前面的例子使用 :message 属性显示你如何能够包含特性的值. ? 对于这个 helper 的默认错误信息是 "is not included in the list". ?

2.7?length 长度

这个 helper 校验的是属性值的长度. 它提供了多种属性, 因此你可以用不同的方式来声明长度的限制: class?Person < ActiveRecord::Base ??validates?:name, length: { minimum:?2?} ??validates?:bio, length: { maximum:?500?} ??validates?:password, length: {?in:?6..20?} ??validates?:registration_number, length: { is:?6?} end

这些长度方面可用的限制属性是:

  • :minimum -- 属性不能够小于它所声明的长度.
  • :maximum -- 属性不能够大于它所声明的长度.
  • :in(or within) -- 属性长度必须被包含在这个间隔内. 这个值必须是一个区间.
  • :is -- 属性长度必须是这个值相等.

默认的错误信息是依赖于长度校验的类型所决定的. 你能够定制化这些信息, 通过使用 :wrong_length, :too_long, 和 too_short 属性, 以及 %{count} 作为一个占位符用来对应于所设置长度的数字. 你也能够使用 :message 属性来声明错误信息.

class?Person < ActiveRecord::Base ??validates?:bio, length: { maximum:?1000, ????too_long:?"%{count} characters is the maximum allowed"?} end

这个 helper 默认统计字符数, 但你能够用不同的方式来分割这个值, 通过使用 :tokenizer 属性:

class?Essay < ActiveRecord::Base ??validates?:content, length: { ????minimum:?300, ????maximum:?400, ????tokenizer: lambda { |str| str.scan(/\w+/) }, ????too_short:?"must have at least %{count} words", ????too_long:?"must have at most %{count} words" ??} end

注意, 默认的错误信息是复数的(e.g. "is too short (minimum is %{count} characters)"). 正是这个原因, 当 :minimum 是1时, 你应该提供一个个性化的消息, 或者用 presence: true 来替代. 当 :in 或者 :within 有低于1时, 你应该要么提供个性化的消息, 要么优先效用 presence.

?

2.8?numericality 数字化

这个 helper 校验的是, 你的属性必须是数字型的值. 默认的情况下, 它会配对一个可选的标签, 后面跟着的是一个整数型或者浮点数型的数字. 为了详细声明只有整数型的数字才能被允许, 那么需要设置 :only_integer 为 true. ? 如果你设置 :only_integer 为 true, 那么它将会使用 /\A[+-]?\d+\Z/

正则表达式会去校验属性的值. 否则的话, 它会尝试把这个值转换成一个浮点数.

?

warning: 注意, 上面的正则表达式允许后面新的一行字符.

class?Player < ActiveRecord::Base ??validates?:points, numericality:?true ??validates?:games_played, numericality: { only_integer:?true?} end

除了 :only_integer, 这个 helper 也接受下面的属性, 来限制所接受的值:

:greater_than -- 声明的值必须大于所提供的值, ?这个属性默认的错误信息是"must be greater than %{count}".

:greater_than_or_equal_to -- 声明的值必须大于或等于所提供的值. 这个属性默认的错误信息是 "must be greater than or equal to %{count}”

:equal_to — 声明的值必须等于所提供的值。这个属性默认的错误消息是 “must be less equal to %{count}”.

:less_than — 声明的值必须小于所提供的值。这个属性默认错误信息是 “must be less than %{count}”.

:less_than_or_equal_to — 声明的值必须小于等于所提供的值。这个属性默认错误信息 “must be less than or equal to %{count}”.

:odd — 如果设置成true,声明的值必须是一个奇数。这个属性默认的错误信息是 “must be odd”.

:even — 如果设置成true,声明的值必须是一个偶数。这个属性默认的错误信息是 “must be even”.

默认的错误信息是 "is not a number”.

?

2.9?presence 存在

这个helper校验的是,所声明的属性不能为空。它用 blank? 方法来检查,如果值为 nil 或者空字符串,那就是一个字符串为空或者由空格组成。
class Person < ActiveRecord::Base ??validates :name, :login, :email, presence: true end

如果你能确定的是,一个关联性是存在的,你将会需要去测试所关联的对象本身是否是存在的,没有外键被用来映射这关联性。


class LineItem < ActiveRecord::Base ??belongs_to :order ??validates :order, presence: true end

为了去校验所关联的记录,其存在性是必须的,你必须声明 :inverse_of 属性为了关联性:


class Order < ActiveRecord::Base ??has_many :line_items, inverse_of: :order end

如果你校验一个被关联对象的存在性,通过一个 has_one 或者 has_many 关联,它会检查这个对象既不是 blank? 又不是 marked_for_destruction?.

既然 false.blank? 是 true,如果你想要校验 boolean 字段的存在性,你应该使用 validates :field_name, inclusion: { in: [true, false] }.

默认的错误信息是 “can’t be blank”.

2.10?absence 缺席

这个helper校验的是,所声明的属性是缺席的。它使用 present? 方法来检查,如果这个值不是 nil 或者 一个空的字符串,也就是说,一个字符串是空的或者由空格组成。
class Person < ActiveRecord::Base ??validates :name, :login, :email, absence: true end

如果你想要确认一个关联性是缺失的,你将会需要去测试该关联性本身是否是缺失的,没有外键被用来映射其关联性。


class LineItem < ActiveRecord::Base ??belongs_to :order ??validates :order, absence: true end

为了去校验所关联的记录,其缺失性是必学的,你必须为了这个关联性而要声明 :inverse_of 属性:


class Order < ActiveRecord::Base ??has_many :line_items, inverse_of: :order end

如果你校验所关联对象的缺失性,通过一个 has_one 或者 has_many 来关联,它会检查该对象既不是 present? 也不是 maked_for_destruction?.

既然 false.present? 是 false,如果你想要校验一个boolean 字段的缺失性,你应该使用 validates :field_name, exclusion: { in:[true, false]}.

默认的错误信息是“must be blank”.

2.11?uniqueness 唯一性

这个 helper 校验的是,该属性值是否唯一,在对象被保存之前。它确实不会在数据库中创建一个唯一性的限制,因此它就可能出现在两个不同的数据库连接里,创建了两条记录是相同的列值,而该列值正是你想要去限制为唯一性的。为了避免这个,你必须这两个列创建一个唯一性索引在你数据库里。参考??the MySQL manual??可以了解到更多关于列的各个索引。
class Account < ActiveRecord::Base ??validates :email, uniqueness: true end

这校验发生在模型的数据表里执行一个SQL查询时,在那个属性用相同的值查询一个已经存在的记录。

这里有一个 :scope 属性,你能够用来声明其他属性,用来限制唯一性的校验:
class Holiday < ActiveRecord::Base ??validates :name, uniqueness: { scope: :year, ????message: "should happen once per year" } end

也有一个 :case_sensitive 属性,你能够用来定义,唯一性限制对于大小写是否敏感。这个属性默认是 true。


class Person < ActiveRecord::Base ??validates :name, uniqueness: { case_sensitive: false } end
warning:注意,一些数据库被设置为大小写不明感。 默认的错误消息是 “has already been taken”。 ?

2.12?validates_with 校验

? 这个helper 传入的是一个特定的类,用来做校验。
class GoodnessValidator < ActiveModel::Validator ??def validate(record) ????if record.first_name == "Evil" ??????record.errors[:base] << "This person is evil" ????end ??end end ? class Person < ActiveRecord::Base ??validates_with GoodnessValidator end ? warning: ?增加到 record.errors[:base] 的错误信息与记录的状态相关联, 这被视为一个整体, 而不是一个特殊的特性. ? validate_with helper 传入一个类, 或则一组类用来执行校验. validates_with 没有默认的错误信息. 在校验的类中, 你必须手工地增加错误信息到记录的错误信息集合中. ? 为了实现校验方法, 你必须拥有一个已经被定义的数据记录行参数, 这个数据记录行会被用来校验. ? 就如同其他的校验, validates_with 有 :if, :unless 和 :on 属性. 如果你带入其他属性, 它会把那些属性发送到校验类中, 作为属性: class?GoodnessValidator < ActiveModel::Validator ??def?validate(record) ????if?options[:fields].any?{|field| record.send(field) ==?"Evil"?} ??????record.errors[:base] <<?"This person is evil" ????end ??end end ? class?Person < ActiveRecord::Base ??validates_with GoodnessValidator, fields: [:first_name,?:last_name] end

注意, 校验对象在整个应用生命周期中只会被初始化一次, 而不是在每一次的校验执行时, 因此在其内部要仔细地使用实例变量.

?

如果你的校验是足够的复杂, 你想要一些实例变量, 你可以简单地使用一个简洁的老旧的Ruby对象来替代:

class?Person < ActiveRecord::Base ??validate?do?|person| ????GoodnessValidator.new(person).validate ??end end ? class?GoodnessValidator ??def?initialize(person) ????@person?= person ??end ? ??def?validate ????if?some_complex_condition_involving_ivars_and_private_methods? ??????@person.errors[:base] <<?"This person is evil" ????end ??end ? ??# ... end

?

2.13?validates_each 校验

这个 helper 校验的是属性, 而不是代码块. 没有预定义的校验方法. 你应该使用代码块来创建它, 每一个传入 validates_each 的属性将会被测试. 在下面的例子中, 我们不想 names 和 surnames 开头是小写字母. class?Person < ActiveRecord::Base ??validates_each?:name,?:surname?do?|record, attr, value| ????record.errors.add(attr,?'must start with upper case')?if?value =~ /\A[a-z]/ ??end end

这个代码块接收到数据记录行, 属性的名称和属性值. 在代码块中你可以做任何你想做的校验. 如果你的校验失败了, 你应该增加一个错误消息到模型中, 因此使它无效.

? original url:?http://guides.rubyonrails.org/active_record_validations.html#validation-helpers

?

上一篇: 基于Android 平台简易即时通讯的研究与设计[转] 下一篇: 没有下一篇了!
发表评论
用户名: 匿名