views:

457

answers:

3

I have a model with a couple of accepts_nested_attributes_for. There is a requirement that I have at least one of each of the nested attributes when saving and moving on.

However, validation occurs pre-save, so when I'm removing an item and moving on, it let's it through.

How can I validate that when I've saved, I have at least one item of each nested type there?

A: 

You can always call valid? on a model and it will run the validation.

Kathy Van Stone
I realise that, but I need it to happen before save - the parent object get's saved before the nested attributes
Neil Middleton
If any validation returns false the entire transaction is rolled back. Regardless of whether it's in the parent or nested models.
EmFi
A: 

I believe you're looking for validates_associated

BJ Clark
+5  A: 

There's a bug with accepts_nested_attributes_for. Meaning you have to be a little more devious when it comes to validations in the parent model.

You could use an :after_save callback in each of your nested models to check if it's the last one. But if there's many nested associations where you want to ensure at least one, this isn't very DRY.

This is however a valid workaround for the linked bug:

class Whatever < ActiveRecord::Base
  :has_many => :association_a
  :has_many => :association_b

  def ensure_minimum_associations
    bad_associations =  [:association_a, :association_b].
      select{|assoc| self.send(assoc).all?{|a| a.marked_for_destruction?}}
    unless bad_associations.empty?
      bad_associations.each do |association|
        errors.add_to_base "Each #{self.class.name.downcase} must retain at least one #{association}"
      end
      return false
    end
  end
end
EmFi