如何使用不同的验证规则集并能够在before_validation中更改它?

时间:2011-11-23 20:54:28

标签: validation ruby-on-rails-3.1

假设我有一个带有一些验证规则的模型:

class Customer < ActiveRecord::Base
  belongs_to :country


  validates :company_name,
            :presence => {
                :if => :name_empty?,
                :message => 'field required'
            },
            :length => {
                :maximum => 255,
                :too_long => 'max field length is %{count}'
            }
  validates :firstname,
            :presence => {
                :if => :company_name_empty?,
                :message => 'field required'
            },
            :length => {
                :maximum => 64,
                :too_long => 'max field length is %{count}'
            }
  validates :lastname,
            :presence => {
                :if => :company_name_empty?,
                :message => 'field required'
            },
            :length => {
                :maximum => 64,
                :too_long => 'max field length is %{count}'
            }

end

并且在某些条件下我想完全改变这些规则 - 使用不同的规则集。我怎样才能做到这一点?有条件的验证和分组对我来说不起作用(也许是因为我已经在我的规则中有一些“:if”)。在CakePHP中,我将在beforeValidate()中更改验证规则,并将新的规则数组传递给模型,但我不知道如何在Rails中执行类似的操作。

1 个答案:

答案 0 :(得分:1)

您已经使用了一些自定义条件方法 - :if => :name_empty?调用@customer.name_empty?(其中@customer是此类的实例)以确定是否执行验证。您的代码示例缺少这些方法的定义,但它们可能非常复杂。

如果您想根据某些条件更改长度验证器的:maximum选项,则可以在同一属性上定义另一个验证器。

validates :firstname, length: { maximum: 64, if: :normal_user? }
validates :firstname, length: { maximum: 666, if: :satan? }

如果只有两个可能的值,您甚至可以使用相同的方法:

validates :firstname, length: { maximum: 64, if: :normal_user? }
validates :firstname, length: { maximum: 666, unless: :normal_user? }

然后将始终执行验证,只会更改最大值。

如果您使用第一个示例,则@customer.normal_user? || @customer.satan?将执行验证。如果这两个方法都返回false,则不会执行验证。

* 注意:如果两种方法都返回true,我不确定会发生什么,所以你需要检查并注意。我怀疑它会按预期工作。 *

你可能已经读过这个,但由于这个问题可能被其他人阅读,这里有一些关于(conditional) validations in rails的内容。 validates方法的定义也值得阅读rails api

希望这会对你有所帮助。