验证多列的allow_blank

时间:2014-07-12 14:33:58

标签: ruby-on-rails validation

我根据active_state验证Realty对象,因此如果它待处理,则允许多个字段为blank

with_options :if => Proc.new { |a| a.active_state == 'pending'} do |realty|
  realty.validates :street, :length => {:in => 1..100}, :allow_blank => true
  realty.validates :postalcode, :numericality => {:only_integer => true}, :length => {:in => 4..5}, :allow_blank => true
  realty.validates :city, :length => {:in => 1..50}, :allow_blank => true
  realty.validates :description, :length => {:maximum => 8000}, :allow_blank => true
  realty.validates :leasing_costs, :numericality => {:only_integer => true}, :length => {:in => 1..9}, :allow_blank => true
end

with_options :if => Proc.new { |a| a.active_state != 'pending'} do |realty|
  realty.validates :street, :length => {:in => 1..100}
  realty.validates :postalcode, :numericality => {:only_integer => true}, :length => {:in => 4..5}
  realty.validates :city, :length => {:in => 1..50}
  realty.validates :description, :length => {:maximum => 8000}
  realty.validates :leasing_costs, :numericality => {:only_integer => true}, :length => {:in => 1..9}
end

唯一的区别是那些:allow_blank => true选项。

我想让这段代码更干,所以我的尝试是使用普通的验证块一次:

validates :street, :length => {:in => 1..100}
validates :postalcode, :numericality => {:only_integer => true}, :length => {:in => 4..5}
validates :city, :length => {:in => 1..50}
validates :description, :length => {:maximum => 8000}
validates :leasing_costs, :numericality => {:only_integer => true}, :length => {:in => 1..9}

然后只需在所有这些字段上调用一些函数,以防状态为挂起

with_options :if => Proc.new { |a| a.active_state == 'pending'} do |realty|
  realty.allow_blank_of :street, :postalcode, :city, :description, :leasing_costs
end

与所有validates_uniqueness_of :x, :y, :z方法类似。

我无法找到符合我需要的功能。我该如何处理?

3 个答案:

答案 0 :(得分:1)

如果:allow_blank选项采用过程会很好,但我不认为它会这样做。但是,您可以使用:if选项获得相同的结果,因为:allow_blank实际上是一种说法"如果属性为空,则不要运行此验证要求" 。所以试试这个:

with_options :if => Proc.new { |a| a.active_state == 'pending' ? a.present? : true } do |realty|
  realty.validates :street, :length => {:in => 1..100}
  realty.validates :postalcode, :numericality => {:only_integer => true}, :length => {:in => 4..5}
  realty.validates :city, :length => {:in => 1..50}
  realty.validates :description, :length => {:maximum => 8000}
  realty.validates :leasing_costs, :numericality => {:only_integer => true}, :length => {:in => 1..9}
end

本案例中的proc表示......如果active_state'pending'且属性存在,则执行此验证。但是,如果active_state不是'pending',则该属性不允许为空,因此请始终运行验证。我希望我能根据你的需要得到正确的逻辑。

答案 1 :(得分:1)

来自pdobb's answer

  

但是,使用:if可以获得相同的结果   选项自:allow_blank本质上是一种说法"如果是   属性为空,则不要运行此验证要求"。

基于pdobbs说明allow_blank => true实际上做了什么,我可以将验证范围缩小到:

validates :street, :length => {:in => 1..100}, :unless => :pending?
validates :postalcode, :numericality => {:only_integer => true}, :length => {:in => 4..5}, :unless => :pending?
validates :city, :length => {:in => 1..50}, :unless => :pending?
validates :description, :length => {:maximum => 8000}, :unless => :pending?
validates :leasing_costs, :numericality => {:only_integer => true}, :length => {:in => 1..9}, :unless => :pending?

def pending?
   active_state == "pending"
end

如果active_state是"等待"那么我就跳过所有这些验证。

分配更多DRY:)

答案 2 :(得分:0)

我没有运行这个,但我认为这可能有用

before_commit :build_callback_validator, :on => :create

def build_callback_validator
  validates :street, :length => {:in => 1..100}
  validates :postalcode, :numericality => {:only_integer => true}, :length => {:in => 4..5}
  validates :city, :length => {:in => 1..50}
  validates :description, :length => {:maximum => 8000}
  validates :leasing_costs, :numericality => {:only_integer => true}, :length => {:in => 1..9}
  if self.active_state != 'pending'
    self.allow_blank_of :street, :postalcode, :city, :description, :leasing_costs
  end
end