# Cleaner way to build a "one or the other" validation?

**URL:** <https://www.ruby-forum.com/t/cleaner-way-to-build-a-one-or-the-other-validation/151495>\
**Category:** Rails\
**Created:** [October 22, 2008, 7:22am UTC](https://www.ruby-forum.com/t/cleaner-way-to-build-a-one-or-the-other-validation/151495 "2008-10-22T07:22:17Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![mrkohrea](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4491bb/32.png) [@mrkohrea](https://www.ruby-forum.com/u/mrkohrea)\
**Post date:** [October 22, 2008, 7:22am UTC](https://www.ruby-forum.com/t/cleaner-way-to-build-a-one-or-the-other-validation/151495/1 "2008-10-22T07:22:17Z")

</div>

I have an object called dealer. Dealer has two fields dealer\_number  
and sub\_dealer\_number. It must have 1 OR the other… but not both.  
To validate this I have:

class Dealer \< ActiveRecord::Base  
validate :dealer\_id?

private  
def dealer\_id?  
if number.blank? && sub\_number.blank?  
errors.add\_to\_base(“You must specify either a Dealer Number OR a  
Sub Dealer Number.”)  
elsif (number.length \> 0) && (sub\_number.length \> 0)  
errors.add\_to\_base(“You must specify either a Dealer Number OR  
a Sub Dealer Number.”)  
end  
end  
end

This looks really messy to me. Is there a better way? Thank you for  
your thoughts.

---

<div class="post-metadata">

**Author:** ![mrkohrea](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4491bb/32.png) [@mrkohrea](https://www.ruby-forum.com/u/mrkohrea)\
**Post date:** [October 22, 2008, 7:49am UTC](https://www.ruby-forum.com/t/cleaner-way-to-build-a-one-or-the-other-validation/151495/2 "2008-10-22T07:49:12Z")

</div>

On 21 Oct 2008, at 12:58, gnunix wrote:

> I have an object called dealer. Dealer has two fields dealer\_number  
> and sub\_dealer\_number. It must have 1 OR the other… but not both.  
> To validate this I have:

Use the Xor operator ( ^ ) ?

Fred

---

<div class="post-metadata">

**Author:** ![mrkohrea](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4491bb/32.png) [@mrkohrea](https://www.ruby-forum.com/u/mrkohrea)\
**Post date:** [October 22, 2008, 5:15pm UTC](https://www.ruby-forum.com/t/cleaner-way-to-build-a-one-or-the-other-validation/151495/3 "2008-10-22T17:15:25Z")

</div>

How about:

def validate\_dealer\_id  
if number.blank? then  
errors.add\_to\_base(“You must specify either a Dealer Number OR a Sub  
Dealer Number.”) if subnumber.blank?  
else  
erros.add\_to\_base(“A dealer can’t have both a dealer number AND a  
sub dealer number”) unless subnumber.blank?  
end  
end

?

Extra bonus kibbitzing:

- Would it make things any easier to store both those  
numbers in a single field, and keep track of whether  
a given dealer is a dealer or a sub in a separate ‘dealer\_type’  
field?
- FWIW–the ruby convention is that methods whose names  
end in a ? return a boolean.

Cheers,

-Roy

---

<div class="post-metadata">

**Author:** ![mrkohrea](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4491bb/32.png) [@mrkohrea](https://www.ruby-forum.com/u/mrkohrea)\
**Post date:** [October 22, 2008, 11:41pm UTC](https://www.ruby-forum.com/t/cleaner-way-to-build-a-one-or-the-other-validation/151495/4 "2008-10-22T23:41:15Z")

</div>

Frederick C. wrote:

> Use the Xor operator ( ^ ) ?
> 
> Fred

Sexy. Thanks.

I changed above to:

class Dealer \< ActiveRecord::Base  
validate :dealer\_id?

private  
def dealer\_id?  
if !(number.blank? ^ sub\_number.blank?)  
errors.add\_to\_base(“You must specify either a Dealer Number OR a  
Sub Dealer Number.”)  
end  
end  
end

Makes me feel less dirty.

---

<div class="post-metadata">

**Author:** ![mrkohrea](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4491bb/32.png) [@mrkohrea](https://www.ruby-forum.com/u/mrkohrea)\
**Post date:** [October 23, 2008, 4:19am UTC](https://www.ruby-forum.com/t/cleaner-way-to-build-a-one-or-the-other-validation/151495/5 "2008-10-23T04:19:45Z")

</div>

Michael K. wrote:

> I don’t think that your above example is any cleaner then my original  
> solution. However, your bonus kibbitzing (lol) I think is a really good  
> thought. I am going to implement this logic on a later iteration.  
> Thanks for this.

Hi Michael,

For future reference, I needed to do something similar a few months ago  
and ended up creating a custom validation. I wrote about it if you want  
to look into it:

[http://per-snicket-y.blogspot.com/2008/04/custom-validations-in-rails-202.html](http://per-snicket-y.blogspot.com/2008/04/custom-validations-in-rails-202.html)

Peace.

---

<div class="post-metadata">

**Author:** ![mrkohrea](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4491bb/32.png) [@mrkohrea](https://www.ruby-forum.com/u/mrkohrea)\
**Post date:** [October 22, 2008, 11:43pm UTC](https://www.ruby-forum.com/t/cleaner-way-to-build-a-one-or-the-other-validation/151495/6 "2008-10-22T23:43:30Z")

</div>

Roy P. wrote:

> How about:
> 
> def validate\_dealer\_id  
> if number.blank? then  
> errors.add\_to\_base(“You must specify either a Dealer Number OR a Sub  
> Dealer Number.”) if subnumber.blank?  
> else  
> erros.add\_to\_base(“A dealer can’t have both a dealer number AND a  
> sub dealer number”) unless subnumber.blank?  
> end  
> end
> 
> ?
> 
> Extra bonus kibbitzing:
> 
> - Would it make things any easier to store both those  
> numbers in a single field, and keep track of whether  
> a given dealer is a dealer or a sub in a separate ‘dealer\_type’  
> field?
> - FWIW–the ruby convention is that methods whose names  
> end in a ? return a boolean.
> 
> Cheers,
> 
> -Roy

I don’t think that your above example is any cleaner then my original  
solution. However, your bonus kibbitzing (lol) I think is a really good  
thought. I am going to implement this logic on a later iteration.  
Thanks for this.
