rails icon indicating copy to clipboard operation
rails copied to clipboard

Handle dependent: nil on ActiveStorage attachments

Open ryanseys opened this issue 2 years ago • 9 comments

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

ryanseys avatar Feb 08 '22 17:02 ryanseys

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.

ghiculescu avatar Feb 08 '22 19:02 ghiculescu

Was able to reproduce on main.

Seems like this is an expected behavior:

  1. https://github.com/rails/rails/blob/b923f70d155c17a217aed5da4624cad1c0f59ce4/activestorage/lib/active_storage/attached/model.rb#L33-L34
  2. 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.

fatkodima avatar Feb 08 '22 22:02 fatkodima

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.

rafaelfranca avatar Feb 08 '22 22:02 rafaelfranca

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.

fatkodima avatar Feb 08 '22 22:02 fatkodima

Yeah. Seems good. Can you open a PR @fatkodima?

rafaelfranca avatar Feb 08 '22 22:02 rafaelfranca

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.

rails-bot[bot] avatar May 09 '22 23:05 rails-bot[bot]

Relevant.

fatkodima avatar May 10 '22 08:05 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.

rails-bot[bot] avatar Aug 08 '22 08:08 rails-bot[bot]

Not stale.

fatkodima avatar Aug 08 '22 09:08 fatkodima

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?

Olgagr avatar Dec 09 '23 15:12 Olgagr

any news about this issue ? :)

cprodhomme avatar Mar 29 '24 14:03 cprodhomme