Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActiveStorage: Detach (instead of purge) attachment after owner record is destroyed?

The Rails API documentation states the following about has_many_attached and has_one_attched methods:

If the :dependent option isn't set, all the attachments will be purged (i.e. destroyed) whenever the record is destroyed.

Specifically, what value should I specify for this option?

like image 973
Tsutomu Avatar asked May 21 '19 12:05

Tsutomu


1 Answers

I'm assuming you are using Rails 5.2. The documentation is not great, but the source code helps to fill in the gaps. Here are a few lines from the relevant file (the code is identical for both has_one_attached and has_many_attached):

# /active_storage/attached/macros.rb

def has_one_attached(name, dependent: :purge_later)

  ...

  if dependent == :purge_later
    after_destroy_commit { public_send(name).purge_later }
  else
    before_destroy { public_send(name).detach }
  end
end

Per the method definition (again, this is identical for both has_one_attached and has_many_attached), :dependent will be set to :purge_later if it is not otherwise specified. So you get the following results when the underlying record is deleted:

has_one_attached :photo

Will result in the photo being purged.

has_one_attached :photo, dependent: :purge_later

Will result in the photo being purged.

has_one_attached :photo, dependent: :detach

Will result in the photo being detached, but the active storage blob being left intact.

Note that anything other than :purge_later will result in attachments being detached rather than purged. So perversely:

has_one_attached :photo, dependent: :purge

Will result in the photo being detached, not purged.

The code appears to have gone through significant refactoring in Rails 6, so this oddity may have been addressed.

UPDATE: This issue has been submitted in Rails 5.2 and there is a pending PR.

like image 106
moveson Avatar answered Oct 01 '22 04:10

moveson