Active Storage
Active Storage 讓您輕鬆地將檔案上傳到雲端服務,例如 Amazon S3、Google Cloud Storage 或 Microsoft Azure Storage,並將這些檔案附加到 Active Record。支援擁有一個主要服務和在其他服務中鏡像以實現冗餘。它還提供了一個磁碟服務,用於測試或本地部署,但重點是雲端儲存。
檔案可以從伺服器上傳到雲端,也可以直接從客戶端上傳到雲端。
此外,還可以針對影像檔案進行轉換,使用隨需變體來調整品質、長寬比、大小或任何其他 MiniMagick 或 Vips 支援的轉換。
您可以在 Active Storage 概述 指南中閱讀更多關於 Active Storage 的資訊。
與其他儲存解決方案的比較
與 Rails 中其他附件解決方案相比,Active Storage 的一個主要區別是它使用了內建的 Blob 和 Attachment 模型(由 Active Record 支援)。這表示現有的應用程式模型不需要修改額外的欄位來與檔案關聯。Active Storage 通過 `Attachment` 連接模型使用多型關聯,然後連接到實際的 `Blob`。
`Blob` 模型儲存附件中繼資料(檔名、內容類型等)及其在儲存服務中的識別碼金鑰。`Blob` 模型不儲存實際的二進位制資料。它們在精神上是不可變的。一個檔案,一個 blob。您也可以將同一個 blob 與多個應用程式模型關聯。如果您想對給定的 `Blob` 進行轉換,其理念是您只需創建一個新的 `Blob`,而不是嘗試修改現有的 `Blob`(當然,如果您不需要先前的版本,以後可以刪除它)。
安裝
執行 `bin/rails active_storage:install` 來複製 active_storage 遷移。
注意:如果找不到該任務,請確認 `config/application.rb` 中是否存在 `require "active_storage/engine"`。
範例
單個附件
class User < ApplicationRecord
# Associates an attachment and a blob. When the user is destroyed they are
# purged by default (models destroyed, and resource files deleted).
has_one_attached :avatar
end
# Attach an avatar to the user.
user.avatar.attach(io: File.open("/path/to/face.jpg"), filename: "face.jpg", content_type: "image/jpeg")
# Does the user have an avatar?
user.avatar.attached? # => true
# Synchronously destroy the avatar and actual resource files.
user.avatar.purge
# Destroy the associated models and actual resource files async, via Active Job.
user.avatar.purge_later
# Does the user have an avatar?
user.avatar.attached? # => false
# Generate a permanent URL for the blob that points to the application.
# Upon access, a redirect to the actual service endpoint is returned.
# This indirection decouples the public URL from the actual one, and
# allows for example mirroring attachments in different services for
# high-availability. The redirection has an HTTP expiration of 5 min.
url_for(user.avatar)
class AvatarsController < ApplicationController
def update
# params[:avatar] contains an ActionDispatch::Http::UploadedFile object
Current.user.avatar.attach(params.require(:avatar))
redirect_to Current.user
end
end
多個附件
class Message < ApplicationRecord
has_many_attached :images
end
<%= form_with model: @message, local: true do |form| %>
<%= form.text_field :title, placeholder: "Title" %><br>
<%= form.textarea :content %><br><br>
<%= form.file_field :images, multiple: true %><br>
<%= form.submit %>
<% end %>
class MessagesController < ApplicationController
def index
# Use the built-in with_attached_images scope to avoid N+1
@messages = Message.all.with_attached_images
end
def create
message = Message.create! params.expect(message: [ :title, :content, images: [] ])
redirect_to message
end
def show
@message = Message.find(params[:id])
end
end
影像附件的`Variation`
<%# Hitting the variant URL will lazy transform the original blob and then redirect to its new service location %>
<%= image_tag user.avatar.variant(resize_to_limit: [100, 100]) %>
`File` 服務策略
Active Storage 支援兩種服務檔案的方式:重新導向和代理。
重新導向
Active Storage 會為檔案產生穩定的應用程式網址,當訪問這些網址時,會重新導向到已簽名的、短期有效的服務網址。這減輕了應用程式伺服器服務檔案資料的負擔。這是預設的檔案服務策略。
當應用程式設定為預設代理檔案時,請使用 `rails_storage_redirect_path` 和 `_url` 路由輔助方法來改用重新導向
<%= image_tag rails_storage_redirect_path(@user.avatar) %>
代理
或者,可以選擇代理檔案。這表示您的應用程式伺服器將響應請求從儲存服務下載檔案資料。這對於從 CDN 服務檔案很有用。
您可以將 Active Storage 設定為預設使用代理
# config/initializers/active_storage.rb
Rails.application.config.active_storage.resolve_model_to_route = :rails_storage_proxy
或者,如果您想明確代理特定附件,可以使用 `rails_storage_proxy_path` 和 `rails_storage_proxy_url` 形式的 URL 輔助方法。
<%= image_tag rails_storage_proxy_path(@user.avatar) %>
直接上傳
Active Storage 及其包含的 JavaScript 函式庫支援直接從客戶端上傳到雲端。
直接上傳安裝
-
將 Active Storage JavaScript 包含在您的應用程式 JavaScript 捆綁包中,或直接引用它。
在應用程式 HTML 中使用自動啟動功能,無需通過資源管道捆綁直接引用
<%= javascript_include_tag "activestorage" %>
在應用程式 HTML 中使用 importmap-rails,無需通過資源管道捆綁,無需自動啟動,作為 ESM 直接引用
# config/importmap.rb pin "@rails/activestorage", to: "activestorage.esm.js"
<script type="module-shim"> import * as ActiveStorage from "@rails/activestorage" ActiveStorage.start() </script>
使用資源管道
//= require activestorage
使用 npm 套件
import * as ActiveStorage from "@rails/activestorage" ActiveStorage.start()
-
使用直接上傳網址標註檔案輸入。
<%= form.file_field :attachments, multiple: true, direct_upload: true %>
-
就這樣!上傳將在表單提交後開始。
直接上傳 JavaScript 事件
事件名稱 | 事件目標 | 事件資料 (`event.detail`) | 說明 |
---|---|---|---|
`direct-uploads:start` | `<form>` | 無 | 已提交包含直接上傳欄位檔案的表單。 |
`direct-upload:initialize` | `<input>` | `{id, file}` | 在表單提交後針對每個檔案分派。 |
`direct-upload:start` | `<input>` | `{id, file}` | 正在開始直接上傳。 |
`direct-upload:before-blob-request` | `<input>` | `{id, file, xhr}` | 在向您的應用程式發出直接上傳中繼資料請求之前。 |
`direct-upload:before-storage-request` | `<input>` | `{id, file, xhr}` | 在發出儲存檔案請求之前。 |
`direct-upload:progress` | `<input>` | `{id, file, progress}` | 儲存檔案請求的進度。 |
`direct-upload:error` | `<input>` | `{id, file, error}` | 發生錯誤。除非取消此事件,否則將顯示「警示」。 |
`direct-upload:end` | `<input>` | `{id, file}` | 直接上傳已結束。 |
`direct-uploads:end` | `<form>` | 無 | 所有直接上傳均已結束。 |
授權
Active Storage 根據 MIT 授權 發布。
支援
API 文件位於
Ruby on Rails 專案的錯誤報告可以提交到這裡
功能請求應在 rails-core 郵件列表中討論,網址如下
- 模組 ActiveStorage::Blobs
- 模組 ActiveStorage::DisableSession
- 模組 ActiveStorage::Reflection
- 模組 ActiveStorage::Representations
- 模組 ActiveStorage::SetCurrent
- 模組 ActiveStorage::Streaming
- 模組 ActiveStorage::Transformers
- 模組 ActiveStorage::VERSION
- 類別 ActiveStorage::AnalyzeJob
- 類別 ActiveStorage::Analyzer
- 類別 ActiveStorage::Attached
- 類別 ActiveStorage::Attachment
- 類別 ActiveStorage::BaseController
- 類別 ActiveStorage::BaseJob
- 類別 ActiveStorage::Blob
- 類別 ActiveStorage::DirectUploadsController
- 類別 ActiveStorage::DiskController
- 類別 ActiveStorage::Error
- 類別 ActiveStorage::FileNotFoundError
- 類別 ActiveStorage::Filename
- 類別 ActiveStorage::FixtureSet
- 類別 ActiveStorage::IntegrityError
- 類別 ActiveStorage::InvariableError
- 類別 ActiveStorage::LogSubscriber
- 類別 ActiveStorage::MirrorJob
- 類別 ActiveStorage::Preview
- 類別 ActiveStorage::PreviewError
- 類別 ActiveStorage::PreviewImageJob
- 類別 ActiveStorage::Previewer
- 類別 ActiveStorage::PurgeJob
- 類別 ActiveStorage::Service
- 類別 ActiveStorage::TransformJob
- 類別 ActiveStorage::UnpreviewableError
- 類別 ActiveStorage::UnrepresentableError
- 類別 ActiveStorage::Variant
- 類別 ActiveStorage::VariantRecord
- 類別 ActiveStorage::VariantWithRecord
- 類別 ActiveStorage::Variation
- G
- V
類別公開方法
gem_version() 連結
以 Gem::Version
的格式回傳目前載入的 Active Storage 版本。
來源:顯示 | 在 GitHub 上
# File activestorage/lib/active_storage/gem_version.rb, line 5 def self.gem_version Gem::Version.new VERSION::STRING end
version() 連結
以 Gem::Version
的格式回傳目前載入的 Active Storage 版本。
來源:顯示 | 在 GitHub 上
# File activestorage/lib/active_storage/version.rb, line 7 def self.version gem_version end