rails
rails copied to clipboard
Handle dependent: nil on ActiveStorage attachments
Steps to reproduce
Setting has_one_attached :content, dependent: nil
on an ActiveRecord model does not work as expected.
Expected behavior
When calling destroy on the record which has has_one_attached :content, dependent: nil
set, I would expect the attachment and blob to not be destroyed.
Actual behavior
The attachment does get destroyed.
System configuration
Rails version: 6.1
Ruby version: 2.7.5
Thanks for the report. Does the issue still exist in Rails 7? Rails 6.1 is not supported for bug fixes anymore, but if it is an issue in 7 we should fix it 👍
It would be helpful if you could provide an executable test case so we can replicate the issue. See https://guides.rubyonrails.org/contributing_to_ruby_on_rails.html#create-an-executable-test-case for details.
Was able to reproduce on main.
Seems like this is an expected behavior:
- https://github.com/rails/rails/blob/b923f70d155c17a217aed5da4624cad1c0f59ce4/activestorage/lib/active_storage/attached/model.rb#L33-L34
- look at
dependent: :destroy
https://github.com/rails/rails/blob/b923f70d155c17a217aed5da4624cad1c0f59ce4/activestorage/lib/active_storage/attached/model.rb#L70
has_one_attached
:dependent
option relates only to blobs, but not to attachments.
Yeah, this is more a feature request but I asked him to open the issue. We should support this to allow soft deletion of records related to the attachment.
So the change is basically
--- a/activestorage/lib/active_storage/attached/model.rb
+++ b/activestorage/lib/active_storage/attached/model.rb
@@ -67,7 +67,8 @@ def #{name}=(attachable)
end
CODE
- has_one :"#{name}_attachment", -> { where(name: name) }, class_name: "ActiveStorage::Attachment", as: :record, inverse_of: :record, dependent: :destroy, strict_loading: strict_loading
+ has_one :"#{name}_attachment", -> { where(name: name) }, class_name: "ActiveStorage::Attachment", as: :record,
+ inverse_of: :record, dependent: (dependent == :purge_later ? :destroy : dependent), strict_loading: strict_loading
has_one :"#{name}_blob", through: :"#{name}_attachment", class_name: "ActiveStorage::Blob", source: :blob, strict_loading: strict_loading
and + for has_many_attached
.
Yeah. Seems good. Can you open a PR @fatkodima?
This issue has been automatically marked as stale because it has not been commented on for at least three months.
The resources of the Rails team are limited, and so we are asking for your help.
If you can still reproduce this error on the 7-0-stable
branch or on main
, please reply with all of the information you have about it in order to keep the issue open.
Thank you for all your contributions.
Relevant.
This issue has been automatically marked as stale because it has not been commented on for at least three months.
The resources of the Rails team are limited, and so we are asking for your help.
If you can still reproduce this error on the 7-0-stable
branch or on main
, please reply with all of the information you have about it in order to keep the issue open.
Thank you for all your contributions.
Not stale.
I'm a little bit confused. Is this issue resolved? How can we set up has_one_attached
to not delete a record from attachments
and blobs
when a record is soft-deleted?
any news about this issue ? :)