модуль ActiveStorage
Active Storage
Active Storage упрощает загрузку и привязку файлов к записям Active Record в облачных сервисах, таких как Amazon S3, Google Cloud Storage или Microsoft Azure Storage. Поддерживает один основной сервис и зеркала в других сервисах для повышения отказоустойчивости. Также предоставляет дисковый сервис для тестирования или локальных развертываний, но основной упор делается на облачное хранилище.
Файлы могут быть загружены с сервера в облако или напрямую с клиента в облако.
Изображения также могут быть преобразованы с помощью вариаций на основе запроса для качества, соотношения сторон, размера или любого другого поддерживаемого MiniMagick или Vips преобразования.
Вы можете узнать больше об Active Storage в руководстве Обзор Active Storage.
Сравнение с другими решениями хранения
Ключевое отличие работы Active Storage от других решений привязки в Rails заключается в использовании встроенных моделей Blob и Attachment (поддерживаемые Active Record). Это означает, что существующие модели приложений не требуют изменения с добавлением дополнительных столбцов для связи с файлами. Active Storage использует полиморфные ассоциации через Attachment модель соединения, которая затем подключается к фактической Blob.
Blob модели хранят метаданные вложений (имя файла, тип содержимого и т. д.) и ключ идентификатора в хранилище. Blob модели не хранят фактические двоичные данные. Они предназначены для неизменяемости. Один файл, один блок. Вы можете связать один и тот же блок с несколькими моделями приложения. А если вы хотите выполнить преобразование определенного Blob, идея заключается в том, что вы просто создадите новый, а не попытаетесь изменить существующий (хотя, конечно, вы можете удалить предыдущую версию позже, если она вам не нужна).
Установка
Запустите bin/rails active_storage:install для копирования миграций active_storage.
ПРИМЕЧАНИЕ: Если задача не найдена, проверьте, что require "active_storage/engine" присутствует в config/application.rb.
Примеры
Одно вложение:
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.text_area :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.require(:message).permit(: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 генерирует стабильные URL-адреса приложения для файлов, которые при доступе перенаправляют на подписанные, кратковременные URL-адреса службы. Это снимает с серверов приложений нагрузку по обслуживанию данных файла. Это стратегия обслуживания файлов по умолчанию.
Если приложение настроено на проксирование файлов по умолчанию, используйте помощники маршрутов 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
Или, если вы хотите явно проксировать определенные вложения, вы можете использовать помощники URL-адресов в формате rails_storage_proxy_path и rails_storage_proxy_url.
<%= image_tag rails_storage_proxy_path(@user.avatar) %>
Прямые загрузки
Active Storage, со своей интегрированной JavaScript-библиотекой, поддерживает загрузку файлов напрямую с клиента в облако.
Установка прямой загрузки
-
Включите JavaScript Active Storage в пакет JavaScript вашего приложения или обратитесь к нему напрямую.
Требование напрямую без объединения через конвейер активов в HTML-приложения с автоматическим запуском:
<%= javascript_include_tag "activestorage" %>
Требование через importmap-rails без объединения через конвейер активов в HTML-приложении без автоматического запуска как 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()
-
Помечайте поля ввода файлов URL-адресом прямой загрузки.
<%= 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}' | Произошла ошибка. Будет показано всплывающее окно "alert", если это событие не отменено. |
| 'direct-upload:end' | '<input>' | '{id, file}' | Прямая загрузка завершена. |
| 'direct-uploads:end' | '<form>' | Нет | Все прямые загрузки завершены. |
Лицензия
Active Storage распространяется на условиях лицензии MIT.
Поддержка
Документация API находится по адресу:
Отчеты об ошибках для проекта Ruby on Rails можно подать здесь:
Заявки на новые функции следует обсуждать на рассылке rails-core по этому адресу:
Публичные методы класса
# File activestorage/lib/active_storage/gem_version.rb, line 5 def self.gem_version Gem::Version.new VERSION::STRING end
Возвращает текущую загруженную версию Active Storage в виде Gem::Version.
# File activestorage/lib/active_storage.rb, line 367
def self.replace_on_assign_to_many
ActiveStorage.deprecator.warn("config.active_storage.replace_on_assign_to_many is deprecated and has no effect.")
end # File activestorage/lib/active_storage.rb, line 371
def self.replace_on_assign_to_many=(value)
ActiveStorage.deprecator.warn("config.active_storage.replace_on_assign_to_many is deprecated and has no effect.")
end # File activestorage/lib/active_storage.rb, line 375
def self.silence_invalid_content_types_warning
ActiveStorage.deprecator.warn("config.active_storage.silence_invalid_content_types_warning is deprecated and has no effect.")
end # File activestorage/lib/active_storage.rb, line 379
def self.silence_invalid_content_types_warning=(value)
ActiveStorage.deprecator.warn("config.active_storage.silence_invalid_content_types_warning is deprecated and has no effect.")
end # File activestorage/lib/active_storage/version.rb, line 7 def self.version gem_version end
Возвращает текущую загруженную версию Active Storage в виде Gem::Version.
© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.