New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inconsistent behavior of dependent: :destroy_async
for thehas_many
association
#42430
Comments
Thanks for the detailed bug report. Would you be interested in helping to contribute a fix? A huge start would be to add a failing test that replicates the bug: https://github.com/rails/rails/blob/main/activerecord/test/activejob/destroy_association_async_test.rb would be a good place for it to live. I imagine the bug is somewhere in here https://github.com/rails/rails/blob/main/activerecord/lib/active_record/associations/has_many_association.rb#L10 but we can confirm that once we have a failing test. If you haven't done it before, https://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html#contributing-to-the-rails-code runs you through setting up a rails dev environment so you can run the tests locally and make a PR! |
@ghiculescu I will prepare a PR with a fix. |
I've submitted a draft for this. It will be easier to discuss things with a context. See #42452 |
There are two ways for deleting an associated record: 1. by deleting it explicitly (i.e. `parent.has_many.first.destroy!`), 2. by replacing the association (i.e. `parent.has_many = []`). Previously, Active Record respected the asynchronous deletion only with the first approach. When replacing the association, it just detached the record(s) from the parent without removing them from the database (via enqueuing relevant background job). Make the dependent option consistent and cleanup records from the database even when removing them via replacing the association. Fixes rails#42430
This issue has been automatically marked as stale because it has not been commented on for at least three months. |
This is still relevant. The PR awaits code review (see #42452). |
This issue has been automatically marked as stale because it has not been commented on for at least three months. |
@rails-bot This is still relevant and the PR is pending. |
It allows extending the job with additional options without breaking people's applications. See https://github.com/rails/rails/pull/42452/files#r678742445. [rails#42430]
This issue has been automatically marked as stale because it has not been commented on for at least three months. |
@rails-bot This is still relevant. |
Steps to reproduce
Generate a new application:
Apply the following diff (add models):
Expected behavior
Consistent behavior when removing records asynchronously via passing a new list to the
has_many
association (replacing). When you delete an object usingparent.has_many_attr.first.destroy!
, Active Record will update the child's foreign key tonil
and schedule a job to delete an associated record from the database. However, when you will replace the "has many" association and delete the child (usingparent.update!(has_many_attr: [])
) it will only update the foreign key. It won't actually cleanup them from the database:Note that the tag with id = 1 is still there while Active Record should clean it up after calling
book.update!(tags: [])
.Actual behavior
Inconsistent behavior when replacing "has many" association (deleting some records asynchronously). Associated records are updated with the
null
value for the foreign key when replacing the association as the whole, but there are no delete jobs scheduled.Note that using
dependant: :destroy
works as expected:System configuration
Rails version: 6.1.3.2
Ruby version: 3.0.1
The text was updated successfully, but these errors were encountered: