rails: Updating associations with assign_attributes should not persist
assign_attributes should not persist the attributes. But it does for associations.
class Firm
has_many :clients
validates :clients, presence: true
end
class Client
belongs_to :firm
end
firm = Firm.new
firm.clients.build
firm.save
firm.assign_attributes({clients: []})
saved = firm.save
saved becomes false, but it has already been persisted in the call to assign_attributes.
About this issue
- Original URL
- State: closed
- Created 10 years ago
- Reactions: 9
- Comments: 17 (9 by maintainers)
I’d also be very interested in a fix. I think the default behavior of Rails is incredibly dangerous and completely counter-intuitive.
Example
Consider the following scenario:
For this example, we submit the following params:
Expected behavior
As we send an empty name, the validation is failing. Therefore,
update_attributes
returnsfalse
, nothing is persisted and the user is presented with the form again, showing the validation errors.Actual behavior
As expected, the validation fails. The very dangerous thing though is that the group associations are saved anyway, as the Rails-generated
_ids
-setter (and thusassign_attributes
andupdate_attributes
) automatically save the association.Temporary workaround
I’ve written a mini-library to work around this issue. If you use it, make sure you read through it and understand it fully, as it does not handle everything properly so it’s important you know exactly what it does and what it doesn’t do.
Conclusion & plea
I’d be very happy if this could be fixed by someone with AR development experience - I think I don’t know the code base well enough to implement such a fundamental change.
Thank you folks for having a look at this 👍
Actually, it would be nice it this could be changed in rails 5. I would like the assignment of a
has_one, has_many, has_and_belongs_to_many
to not save automatically be default, but instead do the same as thecollection.build
method. This would be way more intuitive.Maybe I should have read http://guides.rubyonrails.org/association_basics.html#has-many-association-reference-when-are-objects-saved-questionmark But I still think this is counter intuitive.
I’ve posted my proposal for this at https://groups.google.com/forum/?fromgroups#!topic/rubyonrails-core/-BP3yigVvII
This hit me as well. And it’s true that it’s dangerous, since it might change data when you rely on validations that should prevent that! I have a form that shows an error upon submit due to a validation but still silently persists the changes in that very moment. The workaround by remofritzsche works well in my case.
The Gist has been moved to https://gist.github.com/sudoremo/4204e399e547ff7e3afdd0d89a5aaf3e.
The proposal posted by Jason Barnabe five years ago has been migrated and is collecting dust here now: https://discuss.rubyonrails.org/t/using-accepts-nested-attributes-for-with-assign-attributes-means-immediate-saving-of-associated-model/70525