views:

355

answers:

1

I am running into an issue when trying to apply an :if condition to a validates_associated validation. The if condition works for validates_presence_of, but not for validates_associated, and the form (with two models in it) works correctly, except that the validation still returns an error, regardless of whether the if condition is true or false.

validates_associated :departures, :if => :cruise?
validates_presence_of :ship_name, :if => :cruise?

def cruise?
  item_marker == 1
end

# I even tested it using this, and it still returned a validated_associated error
def cruise?
  false
end

#form item
<%= departure_form.date_select :date, :index => (departure.new_record? ? '' :       
departure.id), :start_year =>Time.now.year, :order => [:month, :day, :year ],   
:prompt=>true %>

I am using a date select for the :departures field, with a prompt for the for default values (i.e. the first selected option for each field with have a value=""). I believe this is what is causing the problem. I could remove the prompt and just blank out the departure dates for non_cruises in the controller, but that seems sloppy. does anyone have a suggestions? Note, this code uses portions of Ryan Bates's "Handle Multiple Models in One Form" Recipe.

A: 

I figured out what was wrong. My new departures builder function was creating departure objects for all items, whether they were cruises or not. I added an if cruises? statement to the code below and now it works properly.

has_many :departures, :dependent => :destroy

def new_departure_attributes=(departure_attributes)
 departure_attributes.each do |attributes|
   if cruises? #new if statement
     departures.build(attributes)
   end
 end
end
#the following two methods are only used for update actions 
#(the error happens in new/create as well)
def existing_departure_attributes=(departure_attributes)
  departures.reject(&:new_record?).each do |departure|
    attributes = departure_attributes[departure.id.to_s]
    if attributes
      departure.attributes = attributes
    else
      departures.delete(departure)
    end
  end
end

def save_departures
  departures.each do |departure|
    departure.save(false)
  end
end
Dan