1# frozen_string_literal: true
2
3# Mounted uploaders are destroyed by carrierwave's after_commit
4# hook. This hook fetches upload location (local vs remote) from
5# Upload model. So it's necessary to make sure that during that
6# after_commit hook model's associated uploads are not deleted yet.
7# IOW we can not use dependent: :destroy :
8# has_many :uploads, as: :model, dependent: :destroy
9#
10# And because not-mounted uploads require presence of upload's
11# object model when destroying them (FileUploader's `build_upload` method
12# references `model` on delete), we can not use after_commit hook for these
13# uploads.
14#
15# Instead FileUploads are destroyed in before_destroy hook and remaining uploads
16# are destroyed by the carrierwave's after_commit hook.
17
18module WithUploads
19  extend ActiveSupport::Concern
20  include FastDestroyAll::Helpers
21
22  # Currently there is no simple way how to select only not-mounted
23  # uploads, it should be all FileUploaders so we select them by
24  # `uploader` class
25  FILE_UPLOADERS = %w(PersonalFileUploader NamespaceFileUploader FileUploader).freeze
26
27  included do
28    has_many :uploads, as: :model
29    has_many :file_uploads, -> { where(uploader: FILE_UPLOADERS) },
30      class_name: 'Upload', as: :model,
31      dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
32
33    use_fast_destroy :file_uploads
34  end
35
36  def retrieve_upload(_identifier, paths)
37    uploads.find_by(path: paths)
38  end
39end
40