views:

24

answers:

1

I am just starting out in Rails, and trying to develop a simple application. I need to validate three values submitted to the application - each must meet the same validation criteria.

The validation is pretty simple: Value is valid if unqiue, null or equal to "p" or "d".

The following gets me halfway there:

validates_uniqueness_of :value1, :value2, :value3, :allow_nil => true

I think I can use :unless to check whether the value is either "p" or "d", however I can't figure out how.

I guess I am trying to combine validates_uniqueness_of with validates_inclusion_of.

Any suggestions?

+1  A: 

There are a few ways to do that. I'd probably go with something like this:

validates_uniqueness_of :wallport_id, :allow_nil => true, :unless Proc.new { |u| u.wallport_id == 'p' or u.wallport_id == 'd' }

You could also break the extra logic out in to its own method, like this:

validates_uniqueness_of :wallport_id, :unless :has_nonunique_wallport_id

NONUNIQUE_WALLPORT_IDS = ['p', 'd', nil]

def has_nonunique_wallport_id
  NONUNIQUE_WALLPORT_IDS.include? wallport_id
end

or push the whole validation in to its own method, like this:

validate :has_valid_wallport_id

def has_valid_wallport_id
  # check wallport id and return either true or false
end

The best approach probably depends on which you find most readable, which functionality you might want to expose to other parts of your code (eg, does anybody else need to know about valid non-unique wallport ids?), and which things you expect might change (eg, will you add more valid non-unique ids later?). There are also a few different ways of doing the actual check, which again just comes down to what you find most readable and how you think the system might evolve.

John Hyland
Great - I updated the question around the time you answered, to specify that I wanted to validate a number of variables in the same way - I think your solution works fine if I define a validation for each variable, and it is readable. Many thanks. I was banging my head against that one.
dunxd