model validation

I have an 'animal' model that has zero to many animal_options that are other models. Some of these animal_options are mutually exclusive, like 'wet' versus 'dry' and such. How can I validate the animal model to only contain one of these mutually exclusive options?

Breakpointing shows me that my code in Animal.validate doesn't get ran before the invalid animal_options get saved to the database:

class Animal < ActiveRecord::Base

  has_many :animal_animal_options   has_many :animal_options, :through => :animal_animal_options

  def validate     # validate mutually exclusive options     dry = AnimalOption.find_by_name( 'Dry' )     wet = AnimalOption.find_by_name( 'Wet' )     if animal_options.include?( dry ) && animal_options.include?( wet )       errors.add( :animal_options, 'Cannot be dry and wet at the same time' )     end   end


Another issue I'm having is how to make the options pre-selected when editing an animal:

<%= select_tag 'animal_option_id', options_from_collection_for_select( @animal_options, 'id', 'name', @animal.animal_options ), { :multiple => true, :size => @animal_options.size } %>

I get no errors from that tag but it doesn't pre-select anything either.

Any help would be appreciated.


I think your problem is that in the validate below the finds are returning arrays into "dry" and "wet". In addition, they aren't linked to your current Animal. Your current Animal is accessible as "self" in the validate and since you have the relationship defined you can simply do this:

def validate     # create array of option names associated with the current animal     options = {|option|}

    # Animal can't be both wet and dry     if options.include?( 'Wet' ) and options.include( 'Dry' )        errors.add( :animal_options, 'Cannot be dry and wet at the same time' )     end

    # Other option comparisons end


Greg Donald wrote: