rickypai
rickypai

Reputation: 4016

Validate presence of one of multiple attributes in rails

In an multilingual application, a user can input their Chinese and English names. The user can input either or both, but must input at least one name.

class Person < ActiveRecord::Base
  validates :zh_name, :presence => true
  validates :en_name, :presence => true
  validates :fr_name, :presence => true
end

Since the built-in :validates_presence_of method can only validate both attributes at once, is there a way to validate the presence of at least one of many attributes in rails?

Like a magical, validates_one_of :zh_name, :en_name, :fr_name

Thank you in advance,

Upvotes: 25

Views: 14654

Answers (4)

ReggieB
ReggieB

Reputation: 8257

Taking @micapam's answer a step futher, may I suggest:

validate :has_a_name

def has_a_name
  unless [zh_name?, en_name?, fr_name?].include?(true)
    errors.add :base, 'You need at least one name in some language!'
  end
end 

Upvotes: 12

micapam
micapam

Reputation: 763

validate :has_a_name

def has_a_name
  unless [zh_name, en_name, fr_name].any?{|val| val.present? }
    errors.add :base, 'You need at least one name in some language!'
  end
end 

Max Williams' answer is fine, but I didn't see the need to count hits when any? returns a boolean.

Upvotes: 2

Max Williams
Max Williams

Reputation: 32955

validate :at_least_one_name

def at_least_one_name
  if [self.zh_name, self.en_name, self.fr_name].reject(&:blank?).size == 0
    errors[:base] << ("Please choose at least one name - any language will do.")
  end
end      

Upvotes: 35

beanie
beanie

Reputation: 1448

just a quick shot out, you can pass a "if" or "unless" to the validator, maybe you can get it working this way. i have something like this in mind

validates :zh_name, :presence => { :if => (fr_name.blank? && en_name.blank?) }

Upvotes: 2

Related Questions