Q:

Associations: Prevent Save if the Collection as a Whole is Invalid

I need to validate a model containing an associated collection which requires
a field to be unique within a has_many collection.
For example, if I have the following classes:
class Match < ActiveRecord::Base
  has_many :match_items, dependent: :destroy
  validates_associated :match_items
end

class MatchItem < ActiveRecord::Base
  belongs_to :match
  validates_uniqueness_of :user_type, scope: :match_id
end

I create a Match like this:
items = [
  MatchItem.new(user_type: 'test'),
  MatchItem.new(user_type: 'test')
]
match = Match.new(match_items: items)
match.save # Erroneously returns true

I want the Match creation to fail.
While the uniqueness validator in the MatchItem class does prevent the collection from containing multiple user types, I would prefer that the Match creation fail. Instead, the match is created without error, although it contains only one of the specified match items.
I think the problem is that validates_associated calls valid? on each MatchItem before saving the Match, but each MatchItem, before it is added to the Match, is valid on its own.
What's the best way to prevent the Match from saving when its match_items collection does not contain unique values?

A:

It looks like this is an open issue (#11851) in the rails project. As Peter helped point out, the problem here comes when you build the records vs creating them separately. As a work around for now, I am just creating all the objects before assigning them to the collection.
# This one fails properly
items = MatchItem.create([ { user_type: 'test' }, { user_type: 'test' } ])
Match.create!(match_items: items)

# While this one succeeds when it shouldn't
items = [
  MatchItem.new(user_type: 'test'),
  MatchItem.new(user_type: 'test')
]
match = Match.new(match_items: items)
match.save # Erroneously returns true

