views:

83

answers:

2

Hi all,

Have a nested form, the relationship is like so

class Inspection < ActiveRecord::Base
  has_many :inspection_components
  accepts_nested_attributes_for :inspection_components

class InspectionComponent < ActiveRecord::Base
  belongs_to :inspection

I have a custom validate method in Inspection which depends on attributes entered for InspectionComponent. How can I validate - InspectionComponent attributes are not saved or available in validation for Inspection.

Thanks!

EDIT: To make things a bit more clear, here's an example of what I'm trying to do.

Inspection has an attribute status. InspectionComponent also has an attribute status.

The Inspection edit form has nested InspectionComponents and one can update each model's status' on this form. @inspection.status should only be able to be marked 'complete' if all @inspection_component.status == 'complete'.

Therefore, when validating @inspection, I must be able to see what the user entered for @inspection_component.status.

Obviously I have access to the params of both instances in the controller however in the model, where validation should occur, I don't see a way of making this happen.

Hopefully that is clear, thanks.

A: 

You want to use validates_associated.

probably something like:

validates_associated :inspection_components

Do a search on it and look up the api. There are some useful options for this method as well.

DJTripleThreat
Hi - thanks for the reply. The issue here is that this still is doing the validations independently of one another. What I mean is that in Inspection validation, you don't know what has changed in InspectionComponent children and vice versa, in InspectionComponent validation you're not sure what has been submitted for Inspection parent.
46and2
hmm... I might need to see more code to get a better understanding of what you are trying to do. Can you edit your post or give me some more information about what you are trying to do? Usually, I post step-by-step instructions from `rails my_app` to `here is such and such file:` and that gets me a good answer.
DJTripleThreat
Hi DJTripleThreat - I have updated the OP to hopefully be a bit more clear on what I'm trying to do, thanks for looking.
46and2
Ok, check out my other answer. I think this is what you were looking for. Also check out this railscast: http://railscasts.com/episodes/41-conditional-validations
DJTripleThreat
+1  A: 

Ok, a new answer in case the other one I posted is useful to someone else. Specifically for your issue, I think you need something like this:

class Inspection < ActiveRecord::Base
  has_many :inspection_components
  accepts_nested_attributes_for :inspection_components

  # we only care about validating the components being complete
  # if this inspection is complete. Otherwise we don't care.
  validate :all_components_complete, :if => :complete

  def complete
    self.status == 'complete'
  end

  def all_components_complete
    self.inspection_components.each do |component|
      # as soon as you find an incomplete component, this inspection
      # is INVALID!
      Errors.add("field","msg") if component.status != 'complete'
    end
  end
end

class InspectionComponent < ActiveRecord::Base
  belongs_to :inspection
end
DJTripleThreat
Hi DJTT, again, thanks. It's interesting, this type of validation strategy does indeed work on a create of an Inspection and it's InspectionComponents however once the situation is an update, I don't seem to have access to the child InspectionComponents *updated* attributes in the validation method (all_components_complete). When I debug and inspect each inspection_component they still have the old values.
46and2
Ok, let me think about this a little more and see what I can come up with. **EDIT:** I got this to work for me. If you post your email address, I'll send you an email with the project I built. I think you might be doing something wrong with your view or your doing something with the attributes BEFORE you try to update them.
DJTripleThreat