Allow overriding filename in Blob#service_url

This is useful when we have several representations for the same
underlying file, each one with a different name, and we need to provide
a custom download URL based on that name and not that of the underlying
file.
This commit is contained in:
Rosa Gutierrez 2018-01-08 15:44:14 +01:00
parent 7c69351277
commit 8f52d93576
No known key found for this signature in database
GPG Key ID: 345A0CD489B87462
2 changed files with 15 additions and 4 deletions

@ -201,7 +201,7 @@ def representable?
# with users. Instead, the +service_url+ should only be exposed as a redirect from a stable, possibly authenticated URL.
# Hiding the +service_url+ behind a redirect also gives you the power to change services without updating all URLs. And
# it allows permanent URLs that redirect to the +service_url+ to be cached in the view.
def service_url(expires_in: service.url_expires_in, disposition: :inline)
def service_url(expires_in: service.url_expires_in, disposition: :inline, filename: self.filename)
service.url key, expires_in: expires_in, disposition: forcibly_serve_as_binary? ? :attachment : disposition, filename: filename, content_type: content_type
end

@ -50,6 +50,16 @@ class ActiveStorage::BlobTest < ActiveSupport::TestCase
end
end
test "urls allow for custom filename" do
blob = create_blob(filename: "original.txt")
new_filename = ActiveStorage::Filename.new("new.txt")
freeze_time do
assert_equal expected_url_for(blob), blob.service_url
assert_equal expected_url_for(blob, filename: new_filename), blob.service_url(filename: new_filename)
end
end
test "purge deletes file from external service" do
blob = create_blob
@ -66,8 +76,9 @@ class ActiveStorage::BlobTest < ActiveSupport::TestCase
end
private
def expected_url_for(blob, disposition: :inline)
query_string = { content_type: blob.content_type, disposition: "#{disposition}; #{blob.filename.parameters}" }.to_param
"/rails/active_storage/disk/#{ActiveStorage.verifier.generate(blob.key, expires_in: 5.minutes, purpose: :blob_key)}/#{blob.filename}?#{query_string}"
def expected_url_for(blob, disposition: :inline, filename: nil)
filename ||= blob.filename
query_string = { content_type: blob.content_type, disposition: "#{disposition}; #{filename.parameters}" }.to_param
"/rails/active_storage/disk/#{ActiveStorage.verifier.generate(blob.key, expires_in: 5.minutes, purpose: :blob_key)}/#{filename}?#{query_string}"
end
end