Validating uniqueness of nested model on create
I recently ran into the issue where I setup a uniqueness validator on a field, with a scope on the parent’s ID. This was fine for updating with an existing parent, but if I ever created two or more new fields, the validation would fail because there was no ID on the parent model yet for the child to validate against. This is apparently still an open issue with rails, as found by this url: https://rails.lighthouseapp.com/projects/8994/tickets/2160-nested_attributes-validates_uniqueness_of-fails. There is a solution in that link, but I have came up with a similar method, with less code that seems to work fine and passes all my tests. I have also added to my solution the ability to add an error to the individual nested items that duplicate. This is how I fixed this (note that I make a lot of assumptions with code, just showing the example):
class Child < ActiveRecord::Base belongs_to :parent validates :value, :uniqueness => { :scope => :parent_id } end class Parent < ActiveRecord::Base has_many :children accepted_nested_attributes_for :children validate :uniqueness_of_children private def uniqueness_of_children hash = {} children.each do |child| if hash[child.value] # This line is needed to form the parent to error out, # otherwise the save would still happen if errors[:"children.value"].blank? errors.add(:"children.value", "duplicate error") end # This line adds the error to the child to view in your fields_for child.errors.add(:value, "has already been taken") end hash[child.value] = true end end end
Let me know if you try this out and it works for you, or if it needs any improvements. Thanks!