mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Introduce ActiveStorage::Blob#representation
This commit is contained in:
parent
8bcb4fab36
commit
445c682a84
4 changed files with 73 additions and 0 deletions
|
@ -15,6 +15,7 @@
|
||||||
# If you need to create a derivative or otherwise change the blob, simply create a new blob and purge the old one.
|
# If you need to create a derivative or otherwise change the blob, simply create a new blob and purge the old one.
|
||||||
class ActiveStorage::Blob < ActiveRecord::Base
|
class ActiveStorage::Blob < ActiveRecord::Base
|
||||||
class UnpreviewableError < StandardError; end
|
class UnpreviewableError < StandardError; end
|
||||||
|
class UnrepresentableError < StandardError; end
|
||||||
|
|
||||||
self.table_name = "active_storage_blobs"
|
self.table_name = "active_storage_blobs"
|
||||||
|
|
||||||
|
@ -155,6 +156,31 @@ class ActiveStorage::Blob < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# Returns an ActiveStorage::Preview instance for a previewable blob or an ActiveStorage::Variant instance for an image blob.
|
||||||
|
#
|
||||||
|
# blob.representation(resize: "100x100").processed.service_url
|
||||||
|
#
|
||||||
|
# Raises ActiveStorage::Blob::UnrepresentableError if the receiving blob is neither an image nor previewable. Call
|
||||||
|
# ActiveStorage::Blob#representable? to determine whether a blob is representable.
|
||||||
|
#
|
||||||
|
# See ActiveStorage::Blob#preview and ActiveStorage::Blob#variant for more information.
|
||||||
|
def representation(transformations)
|
||||||
|
case
|
||||||
|
when previewable?
|
||||||
|
preview transformations
|
||||||
|
when image?
|
||||||
|
variant transformations
|
||||||
|
else
|
||||||
|
raise UnrepresentableError
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns true if the blob is an image or is previewable.
|
||||||
|
def representable?
|
||||||
|
image? || previewable?
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
# Returns the URL of the blob on the service. This URL is intended to be short-lived for security and not used directly
|
# Returns the URL of the blob on the service. This URL is intended to be short-lived for security and not used directly
|
||||||
# with users. Instead, the +service_url+ should only be exposed as a redirect from a stable, possibly authenticated URL.
|
# 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
|
# Hiding the +service_url+ behind a redirect also gives you the power to change services without updating all URLs. And
|
||||||
|
|
|
@ -65,6 +65,10 @@ class ActiveStorage::Variant
|
||||||
service.url key, expires_in: expires_in, disposition: disposition, filename: blob.filename, content_type: blob.content_type
|
service.url key, expires_in: expires_in, disposition: disposition, filename: blob.filename, content_type: blob.content_type
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns the receiving variant. Allows ActiveStorage::Variant and ActiveStorage::Preview instances to be duck-typed.
|
||||||
|
def image
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def processed?
|
def processed?
|
||||||
|
|
|
@ -7,6 +7,7 @@ class ActiveStorage::PreviewTest < ActiveSupport::TestCase
|
||||||
test "previewing a PDF" do
|
test "previewing a PDF" do
|
||||||
blob = create_file_blob(filename: "report.pdf", content_type: "application/pdf")
|
blob = create_file_blob(filename: "report.pdf", content_type: "application/pdf")
|
||||||
preview = blob.preview(resize: "640x280").processed
|
preview = blob.preview(resize: "640x280").processed
|
||||||
|
|
||||||
assert preview.image.attached?
|
assert preview.image.attached?
|
||||||
assert_equal "report.png", preview.image.filename.to_s
|
assert_equal "report.png", preview.image.filename.to_s
|
||||||
assert_equal "image/png", preview.image.content_type
|
assert_equal "image/png", preview.image.content_type
|
||||||
|
@ -19,6 +20,7 @@ class ActiveStorage::PreviewTest < ActiveSupport::TestCase
|
||||||
test "previewing an MP4 video" do
|
test "previewing an MP4 video" do
|
||||||
blob = create_file_blob(filename: "video.mp4", content_type: "video/mp4")
|
blob = create_file_blob(filename: "video.mp4", content_type: "video/mp4")
|
||||||
preview = blob.preview(resize: "640x280").processed
|
preview = blob.preview(resize: "640x280").processed
|
||||||
|
|
||||||
assert preview.image.attached?
|
assert preview.image.attached?
|
||||||
assert_equal "video.png", preview.image.filename.to_s
|
assert_equal "video.png", preview.image.filename.to_s
|
||||||
assert_equal "image/png", preview.image.content_type
|
assert_equal "image/png", preview.image.content_type
|
||||||
|
|
41
activestorage/test/models/representation_test.rb
Normal file
41
activestorage/test/models/representation_test.rb
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "test_helper"
|
||||||
|
require "database/setup"
|
||||||
|
|
||||||
|
class ActiveStorage::RepresentationTest < ActiveSupport::TestCase
|
||||||
|
test "representing an image" do
|
||||||
|
blob = create_file_blob
|
||||||
|
representation = blob.representation(resize: "100x100").processed
|
||||||
|
|
||||||
|
image = read_image(representation.image)
|
||||||
|
assert_equal 100, image.width
|
||||||
|
assert_equal 67, image.height
|
||||||
|
end
|
||||||
|
|
||||||
|
test "representing a PDF" do
|
||||||
|
blob = create_file_blob(filename: "report.pdf", content_type: "application/pdf")
|
||||||
|
representation = blob.representation(resize: "640x280").processed
|
||||||
|
|
||||||
|
image = read_image(representation.image)
|
||||||
|
assert_equal 612, image.width
|
||||||
|
assert_equal 792, image.height
|
||||||
|
end
|
||||||
|
|
||||||
|
test "representing an MP4 video" do
|
||||||
|
blob = create_file_blob(filename: "video.mp4", content_type: "video/mp4")
|
||||||
|
representation = blob.representation(resize: "640x280").processed
|
||||||
|
|
||||||
|
image = read_image(representation.image)
|
||||||
|
assert_equal 640, image.width
|
||||||
|
assert_equal 480, image.height
|
||||||
|
end
|
||||||
|
|
||||||
|
test "representing an unrepresentable blob" do
|
||||||
|
blob = create_blob
|
||||||
|
|
||||||
|
assert_raises ActiveStorage::Blob::UnrepresentableError do
|
||||||
|
blob.representation resize: "100x100"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue