Using accepts_nested_attributes_for with assign_attributes means immediate saving of associated model

Previously raised at https://github.com/rails/rails/issues/17368

When a parent model accepts_nested_attributes_for a child, and you use assign_attributes on an existing parent, the children are immediately persisted; assign_attributes is just calling children= on the parent. This results in the changes being half-saved and messes things up if you wanted to do further processing before saving.

I propose that for has_one, has_many, and has_and_belongs_to_many associations, assign_attribute avoid persisting by instead:

  1. mark_for_destruction all existing children not present in the passed hash.
  2. Update (but not persist) all existing children present in the passed hash.
  3. Call children.build to create the new children.

I imagine this logic would go in _assign_attribute and would make use of reflect_on_association to figure out what’s what. I’d be willing to attempt to implement this, if it’s a change that would be desired.

2 Likes

I think this would be a really good change and hope you decide to pursue it. The current behavior is not intuitive; one would expect that assign_attributes(nested_params) not persist any changes; if I wanted to persist changes I would use update(nested_params). I’ve been bitten by this and only after poring through the documentation realized why.

1 Like

May I bump this and stress that this is not just a nice to have or not intuitive. It’s a serious issue and even kind of dangerous. It’s been reported 5 years ago and it’s still a problem. Please review the Github thread or request further information so it can be fixed.

OR alternatively, clarify for whatever reason this might be “by design” or hint us at what we’re missing.

Thanks!

1 Like

Interesting. We’ve been raising a lot of improvement ideas this month, but this one truly sounds to me as a “WTF”.

“WTF” describes it quite nicely. :slightly_smiling_face:

Last year I worked on a PR to make make autosave optional for accepts_nested_attributes_for https://github.com/rails/rails/commit/d9c56c87f27cb58ca1e03be2a24cb2ecd6c50675

Has there been any response for the core development team on this? As @jox points out this is a dangerous behaviour; not persisting association attributes when the association fails validation definitely feels like a bug fix rather than a feature request.

I am somewhat confused as to why this hasn’t received any love from core team.

@petrik did you get any traction with your PR? I couldn’t find your commit in any specific PR.