diff options
Diffstat (limited to 'activestorage/lib/active_storage/attached/one.rb')
-rw-r--r-- | activestorage/lib/active_storage/attached/one.rb | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/activestorage/lib/active_storage/attached/one.rb b/activestorage/lib/active_storage/attached/one.rb index 2e5831348e..0244232b2c 100644 --- a/activestorage/lib/active_storage/attached/one.rb +++ b/activestorage/lib/active_storage/attached/one.rb @@ -14,18 +14,20 @@ module ActiveStorage end # Associates a given attachment with the current record, saving it to the database. - # Examples: # # person.avatar.attach(params[:avatar]) # ActionDispatch::Http::UploadedFile object # person.avatar.attach(params[:signed_blob_id]) # Signed reference to blob from direct upload - # person.avatar.attach(io: File.open("~/face.jpg"), filename: "face.jpg", content_type: "image/jpg") + # person.avatar.attach(io: File.open("/path/to/face.jpg"), filename: "face.jpg", content_type: "image/jpg") # person.avatar.attach(avatar_blob) # ActiveStorage::Blob object def attach(attachable) - write_attachment \ - ActiveStorage::Attachment.create!(record: record, name: name, blob: create_blob_from(attachable)) + if attached? && dependent == :purge_later + replace attachable + else + write_attachment build_attachment_from(attachable) + end end - # Returns true if an attachment has been made. + # Returns +true+ if an attachment has been made. # # class User < ActiveRecord::Base # has_one_attached :avatar @@ -36,6 +38,14 @@ module ActiveStorage attachment.present? end + # Deletes the attachment without purging it, leaving its blob in place. + def detach + if attached? + attachment.destroy + write_attachment nil + end + end + # Directly purges the attachment (i.e. destroys the blob and # attachment and deletes the file on the service). def purge @@ -53,6 +63,19 @@ module ActiveStorage end private + def replace(attachable) + blob.tap do + transaction do + detach + write_attachment build_attachment_from(attachable) + end + end.purge_later + end + + def build_attachment_from(attachable) + ActiveStorage::Attachment.new(record: record, name: name, blob: create_blob_from(attachable)) + end + def write_attachment(attachment) record.public_send("#{name}_attachment=", attachment) end |