diff options
Diffstat (limited to 'activestorage/lib')
8 files changed, 40 insertions, 20 deletions
diff --git a/activestorage/lib/active_storage/attached.rb b/activestorage/lib/active_storage/attached.rb index 9c4b6d5d1d..c08fd56652 100644 --- a/activestorage/lib/active_storage/attached.rb +++ b/activestorage/lib/active_storage/attached.rb @@ -8,10 +8,10 @@ module ActiveStorage # Abstract base class for the concrete ActiveStorage::Attached::One and ActiveStorage::Attached::Many # classes that both provide proxy access to the blob association for a record. class Attached - attr_reader :name, :record + attr_reader :name, :record, :dependent - def initialize(name, record) - @name, @record = name, record + def initialize(name, record, dependent:) + @name, @record, @dependent = name, record, dependent end private diff --git a/activestorage/lib/active_storage/attached/macros.rb b/activestorage/lib/active_storage/attached/macros.rb index f3879ee2e3..35a081adc4 100644 --- a/activestorage/lib/active_storage/attached/macros.rb +++ b/activestorage/lib/active_storage/attached/macros.rb @@ -26,7 +26,7 @@ module ActiveStorage def has_one_attached(name, dependent: :purge_later) class_eval <<-CODE, __FILE__, __LINE__ + 1 def #{name} - @active_storage_attached_#{name} ||= ActiveStorage::Attached::One.new("#{name}", self) + @active_storage_attached_#{name} ||= ActiveStorage::Attached::One.new("#{name}", self, dependent: #{dependent == :purge_later ? ":purge_later" : "false"}) end CODE @@ -65,7 +65,7 @@ module ActiveStorage def has_many_attached(name, dependent: :purge_later) class_eval <<-CODE, __FILE__, __LINE__ + 1 def #{name} - @active_storage_attached_#{name} ||= ActiveStorage::Attached::Many.new("#{name}", self) + @active_storage_attached_#{name} ||= ActiveStorage::Attached::Many.new("#{name}", self, dependent: #{dependent == :purge_later ? ":purge_later" : "false"}) end CODE diff --git a/activestorage/lib/active_storage/attached/one.rb b/activestorage/lib/active_storage/attached/one.rb index 2e5831348e..ac90f32d95 100644 --- a/activestorage/lib/active_storage/attached/one.rb +++ b/activestorage/lib/active_storage/attached/one.rb @@ -21,11 +21,14 @@ module ActiveStorage # person.avatar.attach(io: File.open("~/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 create_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 @@ -53,6 +56,19 @@ module ActiveStorage end private + def replace(attachable) + blob.tap do + transaction do + destroy + write_attachment create_attachment_from(attachable) + end + end.purge_later + end + + def create_attachment_from(attachable) + ActiveStorage::Attachment.create!(record: record, name: name, blob: create_blob_from(attachable)) + end + def write_attachment(attachment) record.public_send("#{name}_attachment=", attachment) end diff --git a/activestorage/lib/active_storage/service.rb b/activestorage/lib/active_storage/service.rb index ce736b8728..b80fdea1ab 100644 --- a/activestorage/lib/active_storage/service.rb +++ b/activestorage/lib/active_storage/service.rb @@ -77,7 +77,7 @@ module ActiveStorage raise NotImplementedError end - # Return true if a file exists at the +key+. + # Return +true+ if a file exists at the +key+. def exist?(key) raise NotImplementedError end diff --git a/activestorage/lib/active_storage/service/azure_storage_service.rb b/activestorage/lib/active_storage/service/azure_storage_service.rb index d0ee2273c5..895cc9c2f1 100644 --- a/activestorage/lib/active_storage/service/azure_storage_service.rb +++ b/activestorage/lib/active_storage/service/azure_storage_service.rb @@ -59,12 +59,16 @@ module ActiveStorage end end - def url(key, expires_in:, disposition:, filename:, content_type:) + def url(key, expires_in:, filename:, disposition:, content_type:) instrument :url, key do |payload| base_url = url_for(key) - generated_url = signer.signed_uri(URI(base_url), false, permissions: "r", - expiry: format_expiry(expires_in), content_type: content_type, - content_disposition: "#{disposition}; filename=\"#{filename}\"").to_s + generated_url = signer.signed_uri( + URI(base_url), false, + permissions: "r", + expiry: format_expiry(expires_in), + content_disposition: disposition, + content_type: content_type + ).to_s payload[:url] = generated_url diff --git a/activestorage/lib/active_storage/service/disk_service.rb b/activestorage/lib/active_storage/service/disk_service.rb index 1d121dcb6c..f600753a08 100644 --- a/activestorage/lib/active_storage/service/disk_service.rb +++ b/activestorage/lib/active_storage/service/disk_service.rb @@ -56,7 +56,7 @@ module ActiveStorage end end - def url(key, expires_in:, disposition:, filename:, content_type:) + def url(key, expires_in:, filename:, disposition:, content_type:) instrument :url, key do |payload| verified_key_with_expiration = ActiveStorage.verifier.generate(key, expires_in: expires_in, purpose: :blob_key) @@ -64,9 +64,9 @@ module ActiveStorage if defined?(Rails.application) Rails.application.routes.url_helpers.rails_disk_service_path \ verified_key_with_expiration, - disposition: disposition, filename: filename, content_type: content_type + filename: filename, disposition: disposition, content_type: content_type else - "/rails/active_storage/disk/#{verified_key_with_expiration}/#{filename}?disposition=#{disposition}&content_type=#{content_type}" + "/rails/active_storage/disk/#{verified_key_with_expiration}/#{filename}?content_type=#{content_type}&disposition=#{disposition}" end payload[:url] = generated_url diff --git a/activestorage/lib/active_storage/service/gcs_service.rb b/activestorage/lib/active_storage/service/gcs_service.rb index e656f2c69f..ebf24a36d7 100644 --- a/activestorage/lib/active_storage/service/gcs_service.rb +++ b/activestorage/lib/active_storage/service/gcs_service.rb @@ -47,10 +47,10 @@ module ActiveStorage end end - def url(key, expires_in:, disposition:, filename:, content_type:) + def url(key, expires_in:, filename:, content_type:, disposition:) instrument :url, key do |payload| generated_url = file_for(key).signed_url expires: expires_in, query: { - "response-content-disposition" => "#{disposition}; filename=\"#{filename}\"", + "response-content-disposition" => disposition, "response-content-type" => content_type } diff --git a/activestorage/lib/active_storage/service/s3_service.rb b/activestorage/lib/active_storage/service/s3_service.rb index bef2ecbea9..e5d1e56e05 100644 --- a/activestorage/lib/active_storage/service/s3_service.rb +++ b/activestorage/lib/active_storage/service/s3_service.rb @@ -52,10 +52,10 @@ module ActiveStorage end end - def url(key, expires_in:, disposition:, filename:, content_type:) + def url(key, expires_in:, filename:, disposition:, content_type:) instrument :url, key do |payload| generated_url = object_for(key).presigned_url :get, expires_in: expires_in, - response_content_disposition: "#{disposition}; filename=\"#{filename}\"", + response_content_disposition: disposition, response_content_type: content_type payload[:url] = generated_url |