Rails 4 active record validation - conditionally validate presence of 4 attributes if at least one is present while allowing none to be present

断了今生、忘了曾经 提交于 2020-01-16 18:07:07

问题


I have a form with 10 attributes.

Among them I have 4 attributes which I need to apply what I'd call a"mutually conditional presence" Active Record validation.

I want that

  • (A) if one at least is present, then the other 3 must be present
  • (B) still allow none to be present (if the other 3 are blank, then the fourth has the right be be blank)

Here are the four attributes:

  • address_line_1
  • zipcode
  • state
  • country

It means that if the user fills ONE of them then ALL the others have to be present. But if all are blank, it's ok.

So far I have only be able to manage to enforce (A). But I fail to implement (B).

Indeed when i try putting allow_blank: true on one of the 4 attributes validates, then it breaks (A) , as after that, it does not ensure that if on of the attributes is present, the others must be as well.

How to do this?

Here is my current code

spec/models/users

validates :address_line_1,
              presence: true, if: :pa_subelements_mutual_presence?
              length: { maximum: 100,
                        minimum: 3 }
  validates :zipcode, 
              presence: true, if: :pa_subelements_mutual_presence?,
              length: { maximum: 20,
                        minimum: 4} 
  validates :state, 
              presence: true, if: :pa_subelements_mutual_presence?,                  
  validates :country, 
              presence: true, if: :pa_subelements_mutual_presence?,            
              length: { maximum: 50} 

private
 def pa_subelements_mutual_presence? # method to help set validates on mutually dependent for presence for postal address
      lambda { self.address_line_1.present? }  ||
      lambda { self.zipcode.present? }         ||
      lambda { self.state.present? }         ||
      lambda { self.country.present? }
    end

回答1:


It seems to me, it has to be all four or none of them. Not tested, but this should work.

validate :all_or_none

private
    def all_or_none
        errors[:base] << "all or nothing, dude" unless
            (address_line_1.blank? && zipcode.blank? && state.blank? && country.blank?) ||
            (!address_line_1.blank? && !zipcode.blank? && !state.blank? && !country.blank?)
    end

all_or_none will either be true if all four fields are blank or none of them is.



来源:https://stackoverflow.com/questions/30418254/rails-4-active-record-validation-conditionally-validate-presence-of-4-attribut

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!