Spec-Zone.ru › Ruby on Rails 8.0

модуль ActiveStorage

Active Storage

Active Storage упрощает загрузку и ссылку на файлы в облачных сервисах, таких как Amazon S3, Google Cloud Storage или Microsoft Azure Storage, и прикрепление этих файлов к записям Active Record. Поддерживает один основной сервис и зеркала в других сервисах для обеспечения резервирования. Также предоставляет диск-сервис для тестирования или локальных развертываний, но основное внимание уделяется облачному хранилищу.

Файлы могут загружаться с сервера в облако или непосредственно с клиента в облако.

Изображения также могут быть преобразованы с помощью вариантом по требованию для качества, соотношения сторон, размера или любых других поддерживаемых MiniMagick или Vips преобразований.

Подробнее о Active Storage можно узнать в руководстве Обзор Active Storage.

Сравнение с другими решениями хранения данных

Ключевое отличие работы Active Storage от других решений по прикреплению файлов в Rails заключается в использовании встроенных моделей Blob и Attachment (поддерживаемых Active Record). Это означает, что существующие модели приложений не нужно изменять с добавлением дополнительных столбцов для ассоциации с файлами. Active Storage использует полиморфные ассоциации через модель-соединитель Attachment, которая затем соединяется с фактическим Blob.

Модели Blob хранят метаданные прикрепления (имя файла, тип содержимого и т.д.), а также ключ идентификатора в облачном хранилище. Модели 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.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 генерирует стабильные 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-библиотекой поддерживает загрузку файлов напрямую с клиента в облако.

Установка прямой загрузки

  1. Включите 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()
  2. Добавьте к полям ввода файлов URL-адрес прямой загрузки.

    <%= form.file_field :attachments, multiple: true, direct_upload: true %>
  3. Готово! Загрузки начинаются при отправке формы.

События 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 License.

Поддержка

Документация API находится по адресу:

  • api.rubyonrails.org

Отчеты об ошибках для проекта Ruby on Rails можно отправить сюда:

  • github.com/rails/rails/issues

Запросы на новые функции следует обсуждать на рассылке rails-core по адресу:

  • discuss.rubyonrails.org/c/rubyonrails-core

Общедоступные методы класса

gem_version() Показать исходный код
# File activestorage/lib/active_storage/gem_version.rb, line 5
def self.gem_version
  Gem::Version.new VERSION::STRING
end

Возвращает текущую загруженную версию Active Storage в виде Gem::Version.

version() Показать исходный код
# 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.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API