Active Storage Blob¶ ↑
Blob 是一个记录,其中包含有关文件及其在服务上的位置的键的元数据。Blob 可以通过两种方式创建:
-
在文件被服务器端上传到服务之前,通过
create_and_upload!。对于此操作,服务器必须提供可重写的io文件内容。 -
在文件被客户端直接上传到服务之前,通过
create_before_direct_upload!。
第一种选项不需要任何客户端 JavaScript 集成,任何其他处理文件的后端服务都可以使用它。第二种选项速度更快,因为您不使用自己的服务器作为上传的暂存点,并且可以与 Heroku 等不提供大量磁盘空间的部署一起使用。
就 Blob 对特定文件的引用而言,Blob 被认为是不可变的。您可以在后续过程中更新 Blob 的元数据,但不应更新键或更改上传的文件。如果需要创建衍生物或以其他方式更改 Blob,只需创建一个新 Blob 并删除旧的即可。
- MODULE ActiveStorage::Blob::Analyzable
- MODULE ActiveStorage::Blob::Identifiable
- MODULE ActiveStorage::Blob::Representable
- A
- C
- D
- F
- G
- I
- K
- O
- P
- S
- T
- U
- V
- ActiveStorage::Blob::Analyzable
- ActiveStorage::Blob::Identifiable
- ActiveStorage::Blob::Representable
常量
| MINIMUM_TOKEN_LENGTH | = | 28 |
类公共方法
compose(blobs, key: nil, filename:, content_type: nil, metadata: nil) Link
将多个 Blob 连接成一个“组合”Blob。
# File activestorage/app/models/active_storage/blob.rb, line 144 def compose(blobs, key: nil, filename:, content_type: nil, metadata: nil) raise ActiveRecord::RecordNotSaved, "All blobs must be persisted." if blobs.any?(&:new_record?) content_type ||= blobs.pluck(:content_type).compact.first new(key: key, filename: filename, content_type: content_type, metadata: metadata, byte_size: blobs.sum(&:byte_size)).tap do |combined_blob| combined_blob.compose(blobs.pluck(:key)) combined_blob.save! end end
create_and_upload!(key: nil, io:, filename:, content_type: nil, metadata: nil, service_name: nil, identify: true, record: nil) Link
创建新的 Blob 实例,然后将给定 io 的内容上传到服务。Blob 实例将在上传开始前保存,以防止因键冲突而导致上传被覆盖。提供内容类型时,请传递 identify: false 以绕过自动内容类型推断。
# File activestorage/app/models/active_storage/blob.rb, line 95 def create_and_upload!(key: nil, io:, filename:, content_type: nil, metadata: nil, service_name: nil, identify: true, record: nil) create_after_unfurling!(key: key, io: io, filename: filename, content_type: content_type, metadata: metadata, service_name: service_name, identify: identify).tap do |blob| blob.upload_without_unfurling(io) end end
create_before_direct_upload!(key: nil, filename:, byte_size:, checksum:, content_type: nil, metadata: nil, service_name: nil, record: nil) Link
返回一个已保存的 Blob,不将文件上传到服务。此 Blob 将指向一个尚无文件的键。它旨在与客户端上传一起使用,客户端上传将首先创建 Blob 以生成用于上传的签名 URL。此签名 URL 指向 Blob 生成的键。一旦提交了使用直接上传的表单,就可以使用签名 ID 将 Blob 与正确的记录关联起来。
# File activestorage/app/models/active_storage/blob.rb, line 106 def create_before_direct_upload!(key: nil, filename:, byte_size:, checksum:, content_type: nil, metadata: nil, service_name: nil, record: nil) create! key: key, filename: filename, byte_size: byte_size, checksum: checksum, content_type: content_type, metadata: metadata, service_name: service_name end
find_signed(id, record: nil, purpose: :blob_id) Link
您可以使用 Blob 的签名 ID 在客户端引用它,而无需担心被篡改。这对于需要提前创建 Blob 以便在表单提交时进行上传的直接上传特别有用。签名 ID 指向 Blob 生成的键。
签名 ID 也用于通过 BlobsController 为 Blob 创建稳定的 URL。
find_signed!(id, record: nil, purpose: :blob_id) Link
与 find_signed 的工作方式相同,但如果签名 ID 已过期、目的不匹配或被篡改,它将引发 ActiveSupport::MessageVerifier::InvalidSignature 异常。如果有效的签名 ID 找不到记录,它还将引发 ActiveRecord::RecordNotFound 异常。
generate_unique_secure_token(length: MINIMUM_TOKEN_LENGTH) Link
为了防止与不区分大小写的文件系统(尤其是在与将索引视为区分大小写的数据库结合使用时)出现问题,所有生成的 Blob 键将仅包含 base-36 字符字母表,因此将是小写的。为了保持与 has_secure_token 使用的 base-58 编码相同或更高的熵,使用的字节数从标准的 24 增加到 28。
unattached Link
返回未附加到任何记录的 Blob。
实例公共方法
attachments Link
返回关联的 ActiveStorage::Attachment 实例。
audio?() Link
如果此 Blob 的 content_type 在音频范围内,则返回 true,例如 audio/mpeg。
custom_metadata() Link
custom_metadata=(metadata) Link
delete() Link
删除与 Blob 关联的服务上的文件。这应该只在 Blob 也将被删除时进行,否则将导致死引用。在大多数情况下,建议使用 purge 和 purge_later 方法。
download(&block) Link
下载与此 Blob 关联的文件。如果未提供块,则将整个文件读入内存并返回。对于非常大的文件,这将消耗大量 RAM。如果提供了块,则下载将分块流式传输并进行处理。
download_chunk(range) Link
下载与此 Blob 关联的文件的一部分。
filename() Link
返回一个 ActiveStorage::Filename 实例,可用于查询文件名、扩展名以及用于 URL 的安全文件名版本。
image?() Link
如果此 Blob 的 content_type 在图像范围内(例如 image/png),则返回 true。
key() Link
返回指向此 Blob 所关联的服务上文件的键。此键是 Rails 的安全令牌格式(小写)。例如:xtapjjcjiudrlk3tmwyjgpuobabd。此键不应直接暴露给用户。始终使用 signed_id 或验证后的键形式来引用 Blob。
open(tmpdir: nil, &block) Link
将 blob 下载到磁盘上的临时文件中。Yields 临时文件。
临时文件名的前缀是 ActiveStorage- 和 Blob 的 ID。其扩展名与 Blob 的扩展名匹配。
默认情况下,临时文件在 Dir.tmpdir 中创建。要将其创建在其他目录中,请传递 tmpdir:.
blob.open(tmpdir: "/path/to/tmp") do |file| # ... end
给定块执行后,临时文件将自动关闭并删除。
如果下载的数据与 Blob 的校验和不匹配,则引发 ActiveStorage::IntegrityError。
purge() Link
销毁 Blob 记录,然后删除服务上的文件。这是处理不需要的 Blob 的推荐方法。请注意,从服务中删除文件将启动到服务的 HTTP 连接,这可能会很慢或被阻止,因此您不应在事务或回调中使用此方法。在大多数情况下,请使用 purge_later。
purge_later() Link
将一个 ActiveStorage::PurgeJob 加入队列以调用 purge。这是在事务、Active Record 回调或任何其他实时场景中清除 Blob 的推荐方法。
service() Link
返回服务的一个实例,该服务可以全局配置或按附件配置。
service_headers_for_direct_upload() Link
返回用于 service_url_for_direct_upload 请求的标头 Hash。
service_url_for_direct_upload(expires_in: ActiveStorage.service_urls_expire_in) Link
返回一个 URL,可用于直接将文件上传到服务中的此 Blob。此 URL 旨在保持短期以确保安全,并且仅由负责上传的客户端 JavaScript 按需生成。
# File activestorage/app/models/active_storage/blob.rb, line 221 def service_url_for_direct_upload(expires_in: ActiveStorage.service_urls_expire_in) service.url_for_direct_upload key, expires_in: expires_in, content_type: content_type, content_length: byte_size, checksum: checksum, custom_metadata: custom_metadata end
signed_id(purpose: :blob_id, expires_in: nil, expires_at: nil) Link
返回此 Blob 的签名 ID,适用于在客户端引用,而无需担心被篡改。
text?() Link
如果此 Blob 的 content_type 在文本范围内(例如 text/plain),则返回 true。
upload(io, identify: true) Link
将 io 上传到此 Blob 的 key 对应的服务。Blob 被设计为不可变的,因此您不应在文件已上传以匹配 Blob 后使用此方法。如果您想创建衍生的 Blob,则应直接创建一个基于旧 Blob 的新 Blob。
在上传之前,我们将计算校验和,并将其发送到服务进行传输完整性验证。如果校验和与服务收到的不匹配,将引发异常。我们还会测量 io 的大小,并将其存储在 Blob 记录的 byte_size 中。内容类型将从 io 中自动提取,除非您指定了 content_type 并将 identify 设置为 false。
通常,您不需要直接调用此方法。请改用 create_and_upload! 类方法。如果您直接使用此方法,请确保您在已持久化的 Blob 上使用它,否则服务的其他 Blob 的数据可能会被覆盖。
url(expires_in: ActiveStorage.service_urls_expire_in, disposition: :inline, filename: nil, **options) Link
返回 Blob 在服务上的 URL。对于公共文件,这将返回一个永久 URL;对于私有文件,则返回一个短时 URL。私有文件已签名,不适用于公开使用。相反,URL 应仅作为来自稳定、可能已验证的 URL 的重定向暴露。将 URL 隐藏在重定向后面也允许您在不更新所有 URL 的情况下更改服务。
# File activestorage/app/models/active_storage/blob.rb, line 214 def url(expires_in: ActiveStorage.service_urls_expire_in, disposition: :inline, filename: nil, **options) service.url key, expires_in: expires_in, filename: ActiveStorage::Filename.wrap(filename || self.filename), content_type: content_type_for_serving, disposition: forced_disposition_for_serving || disposition, **options end