模型中某些操作的验证

时间:2011-06-24 17:14:37

标签: ruby-on-rails validation

我遇到了一个我以前从未遇到过的问题。我正在处理由另一个程序员编写的代码,这有点混乱。

这是问题所在。我在我的模型中有以下验证:

validates_presence_of :subscription_level,
                      :message => 'please make a selection'
validates_presence_of :shipping_first_name
validates_presence_of :shipping_last_name
validates_presence_of :shipping_address
validates_presence_of :shipping_city
validates_presence_of :shipping_state
validates_presence_of :shipping_postal_code
validates_presence_of :shipping_country
validates_presence_of :billing_first_name
validates_presence_of :billing_last_name
validates_presence_of :billing_address
validates_presence_of :billing_city
validates_presence_of :billing_state
validates_presence_of :billing_postal_code
validates_presence_of :billing_country
validates_presence_of :card_number
validates_numericality_of :card_number
validates_presence_of :card_expiration_month
validates_numericality_of :card_expiration_month
validates_presence_of :card_expiration_year
validates_numericality_of :card_expiration_year
validates_presence_of :card_cvv
validates_numericality_of :card_cvv

我对有问题的控制器有两个动作。一个是new,另一个是redeem。 我想使用new操作执行所有这些验证,但希望跳过其中大部分验证redeem操作。

我现在面临的问题是在控制器中使用valid?也会验证redeem操作不需要的内容。

我怎样才能解决这个问题?

3 个答案:

答案 0 :(得分:14)

这很hacky,但我不得不求助于一个属性标志,可以启用/禁用某些状态下的验证。 (我的具体示例是一个多页面表单,我们最终要验证对象的所有必填字段,但我们只能验证先前页面上提交的数据)

这是一个可能看起来如何的例子:

class Whatever < ActiveRecord::Base
  attr_accessor :enable_strict_validation

  validates_presence_of :name # this always happens
  validates_uniqueness_of :name, :if => :enable_strict_validation
end

然后在其他地方(例如你的控制器),你可以这样做:

@whatever = Whatever.new(...)
@whatever.save  # <= will only run the first validation

@whatever.enable_strict_validation = true
@whatever.save  # <= will run both validations

答案 1 :(得分:4)

控制器不处理验证,因此不是特定于操作的。

但是,验证可以根据对模型进行的更新类型进行限制。更新,创建或保存。

您是否可以将验证仅限制为新记录?

validates_numericality_of :card_cvv, :on => :create

如果没有,您可以编写自定义验证器来处理在您指定的条件下返回true(例如控制器操作),但同样不是“Rails方式”。

最简单的例子是使用validate方法

validate do
  return true if my_action_is_redeem

  self.card_cvv =~ /^\d*$/
end

有关验证的详细信息,请参阅docs

答案 2 :(得分:1)

您可以限制create(新)或更新上的验证(redem操作是更新?)。

您的验证可能是这样的:

validates_presence_of :attribute1, :on => :update #so, only on redem method is validated)

您可以选择在此事件上验证的时间:: create,:update,:save(创建或更新)

更多信息: http://guides.rubyonrails.org/active_record_validations_callbacks.html#on