2

I have a case where a model Parent has many children. The model Child has some validations.

In the Parent model form, I'm building multiple instances of the model Child using nested attributes. The problem is that if one of the children's validations fail, the whole Parent model doesn't save and all the other valid children don't get created.

Is there a way to prevent this behavior and create all the valid associations and silently fail the invalid ones ?

I tried to remove the inverse_of option, but it didn't work.

UPDATE:

It seems that It's not possible, so I came out with this solution. I added the skip_validation to avoid validating the associated records twice (One in the children_attributes= method and the other when saving).

class Parent
  children_attributes=(attributes)
    super

    new_children = self.children.select { |child| child.new_record? }

    new_children.each do |child|
      if child.valid?
        child.skip_validation = true
      else
        self.children.delete(child)
      end
    end 
  end
end

class Child
  attr_accessor :skip_validation    

  validates :attribute, presence: true, unless: :skip_validation?

  def skip_validation?
    !!skip_validation
  end
end
Ruur
  • 185
  • 10
  • I'm not sure, but maybe you should create an object with your nested associations, then iterate it and save the association if it's valid. If it's invalid, use `next` to jump to the next iteration – cercxtrova Feb 27 '19 at 16:24
  • I can do this, but I was wondering if there is a solution to this case using the accepts_nested_attributes_for feature. – Ruur Feb 27 '19 at 16:30
  • 1
    you could use the `reject_if` option in the `accepts_nested_attributes_for ` feature. You have the hash of attributes of the instance that's going to be created, but the only thing I see here is to instantiate the object there and use `valid?`, so that it gets rejected in case it is not valid, but I think that would be a lot of processing I guess :/ – fanta Feb 27 '19 at 16:36
  • @fanta is right, you have an example here https://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html – cercxtrova Feb 27 '19 at 16:48
  • The issue with that solution is that it will run the validation twice. Also, I have a validation which uses a uniqueness using the parent_id scope. I can pass the parent_id in the parameters of every child. It just feels hacky to me. If only there was an option in the accepts_nested_attributes_for to allow saving the parent record. – Ruur Feb 27 '19 at 17:06

0 Answers0