ryanb / nested_form

Rails plugin to conveniently handle multiple models in a single form.
MIT License
1.79k stars 505 forks source link

Nested forms validate uniqueness based on database before transaction #356

Open onebree opened 8 years ago

onebree commented 8 years ago

Rails 4.2.0, nested_form 0.3.2

TL;DR - The validates_uniqueness_on method only compares current records at their current state before the form was submitted.

Location has_many :dids
Location has_many :screened_dids
Location accepts_nested_attributes_for :screened_dids

Did has_one :screened_did

ScreenedDid belongs_to :location
ScreenedDid belongs_to :did
ScreenedDid validates_uniqueness_of :did_id

Given the above associations, say a Location has 5 DIDs and 0 Screened DIDs. On the nested form, I add 5 rows of Screened DIDs, all having the same selected :did_id. Because there were zero Screened DID records for this location before the transaction, all nested objects will be created with different ids but the same :did_id.

If I have 1 Screened DID present with a did_id: 500, and I attempt to create/update one other object with the same, the validation will kick in.

If I have 2 Screened DID objects with different :did_id (500 and 501), and I update both to have the same (502), then the validation will fail, like in the first scenario.

Say in one transaction I attempt to delete ScreenDID id: 1 and create a second record with the :did_id of the first. The form is bounced back, because the :did_id was already present before the transaction, even if the first record was supposed to be deleted.

Finally, if two records are saved in this manner, and are unchanged on the next form update, the two original records will not vall invalid uniqueness. In theory, it should since the objects were in the database before the transaction. I think the validation does not work because they were simply submitted already, and are for some reason exempt from comparing each other.