класс ActiveStorage::Blob
Объект blob — это запись, содержащая метаданные о файле и ключ, указывающий, где этот файл находится на сервисе. Blobs можно создавать двумя способами:
-
До загрузки файла на сервер в службу, с помощью
create_and_upload!. Для этой операции должен быть доступен перематываемыйioс содержимым файла на сервере. -
До прямой загрузки файла на клиенте в службу, с помощью
create_before_direct_upload!.
Первый вариант не требует интеграции с JavaScript на стороне клиента и может использоваться любым другим серверным сервисом, работающим с файлами. Второй вариант быстрее, так как вы не используете собственный сервер в качестве промежуточной точки для загрузки, и он может работать с развертываниями, такими как Heroku, которые не предоставляют большого объема дискового пространства.
Blobs предназначены для неизменяемости в том, что касается ссылки на конкретный файл. Вы можете обновлять метаданные blob на последующих этапах, но не должны обновлять ключ или изменять загруженный файл. Если вам нужно создать производный файл или изменить blob, просто создайте новый blob и удалите старый.
Константы
- MINIMUM_TOKEN_LENGTH
Публичные методы класса
# File activestorage/app/models/active_storage/blob.rb, line 104
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 Создает новый экземпляр blob и затем загружает содержимое данного io в службу. Экземпляр blob будет сохранён перед началом загрузки, чтобы предотвратить перезапись одной загрузки другой из-за столкновения ключей. При указании типа содержимого используйте identify: false для отключения автоматического определения типа содержимого.
# File activestorage/app/models/active_storage/blob.rb, line 118 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
Возвращает сохранённый blob без загрузки файла в службу. Этот blob будет указывать на ключ, где файла ещё нет. Он предназначен для совместного использования с загрузкой на стороне клиента, которая сначала создаст blob, чтобы получить подписанную ссылку для загрузки. Эта подписанная ссылка указывает на ключ, сгенерированный blob. После отправки формы с использованием прямой загрузки blob можно связать с соответствующей записью, используя подписанный идентификатор.
# File activestorage/app/models/active_storage/blob.rb, line 77 def find_signed!(id, record: nil) super(id, purpose: :blob_id) end
Вы можете использовать подписанный идентификатор blob, чтобы сослаться на него на стороне клиента, не боясь подмены. Это особенно полезно для прямых загрузок, где стороне клиента необходимо сослаться на blob, который был создан до самой загрузки при отправке формы.
Подписанный идентификатор также используется для создания стабильных URL-адресов для blob через контроллер Blobs.
# File activestorage/app/models/active_storage/blob.rb, line 127 def generate_unique_secure_token(length: MINIMUM_TOKEN_LENGTH) SecureRandom.base36(length) end
Для предотвращения проблем с регистронезависимыми файловыми системами, особенно в сочетании с базами данных, которые рассматривают индексы как регистрозависимые, все ключи blob будут содержать только алфавит символов base-36 и, следовательно, будут строчными. Для поддержания такого же или более высокого уровня энтропии, как и в кодировании base-58, используемом `has_secure_token`, количество используемых байтов увеличивается до 28 с стандартных 24
Общедоступные методы экземпляров
# File activestorage/app/models/active_storage/blob.rb, line 172
def audio?
content_type.start_with?("audio")
end Возвращает true, если тип содержимого этого фрагмента данных относится к аудиодиапазону, например, audio/mpeg.
# File activestorage/app/models/active_storage/blob.rb, line 279
def delete
service.delete(key)
service.delete_prefixed("variants/#{key}/") if image?
end Удаляет файлы на службе, связанные с фрагментом данных. Это следует делать только в том случае, если фрагмент данных также будет удален, или у вас будет фактически мёртвая ссылка. В большинстве случаев рекомендуется использовать методы purge и purge_later.
# File activestorage/app/models/active_storage/blob.rb, line 250 def download(&block) service.download key, &block end
Загружает файл, связанный с этим фрагментом данных. Если блок не указан, весь файл считывается в память и возвращается. Это потребует много оперативной памяти для очень больших файлов. Если блок указан, загрузка осуществляется потоково и возвращается частями.
# File activestorage/app/models/active_storage/blob.rb, line 162 def filename ActiveStorage::Filename.new(self[:filename]) end
Возвращает экземпляр ActiveStorage::Filename имени файла, который можно использовать для получения имени файла без пути, расширения и очищенной версии имени файла, безопасной для использования в URL.
# File activestorage/app/models/active_storage/blob.rb, line 167
def image?
content_type.start_with?("image")
end Возвращает true, если тип содержимого этого фрагмента данных относится к изображению, например, image/png.
# File activestorage/app/models/active_storage/blob.rb, line 154 def key # We can't wait until the record is first saved to have a key for it self[:key] ||= self.class.generate_unique_secure_token(length: MINIMUM_TOKEN_LENGTH) end
Возвращает ключ, указывающий на файл на службе, связанный с этим фрагментом данных. Ключ имеет формат безопасного токена из Rails в нижнем регистре. Например: xtapjjcjiudrlk3tmwyjgpuobabd. Этот ключ не предназначен для прямого отображения пользователю. Всегда ссылайтесь на фрагменты данных с помощью signed_id или проверенной формы ключа.
# File activestorage/app/models/active_storage/blob.rb, line 267
def open(tmpdir: nil, &block)
service.open key, checksum: checksum,
name: [ "ActiveStorage-#{id}-", filename.extension_with_delimiter ], tmpdir: tmpdir, &block
end Загружает фрагмент данных во временный файл на диске. Возвращает временный файл.
Имя временного файла начинается с ActiveStorage- и идентификатора фрагмента данных. Его расширение соответствует расширению фрагмента данных.
По умолчанию временный файл создаётся в Dir.tmpdir. Чтобы создать его в другом каталоге, передайте tmpdir:.
blob.open(tmpdir: "/path/to/tmp") do |file| # ... end
Временный файл автоматически закрывается и удаляется после выполнения данного блока.
Вызывает исключение ActiveStorage::IntegrityError, если загруженные данные не соответствуют контрольной сумме фрагмента данных.
# File activestorage/app/models/active_storage/blob.rb, line 287 def purge destroy delete rescue ActiveRecord::InvalidForeignKey end
Удаляет запись о фрагменте данных и затем удаляет файл на службе. Это рекомендуемый способ избавления от нежелательных фрагментов данных. Обратите внимание, что удаление файла со службы инициирует HTTP-соединение со службой, что может быть медленным или заблокировано, поэтому не следует использовать этот метод внутри транзакции или в обратных вызовах. Используйте purge_later вместо этого.
# File activestorage/app/models/active_storage/blob.rb, line 295 def purge_later ActiveStorage::PurgeJob.perform_later(self) end
Запускает ActiveStorage::PurgeJob для вызова purge. Это рекомендуемый способ удаления фрагментов данных из транзакции, обратного вызова Active Record или в любом другом сценарии реального времени.
# File activestorage/app/models/active_storage/blob.rb, line 300 def service services.fetch(service_name) end
Возвращает экземпляр службы, который можно настроить глобально или по приложению.
# File activestorage/app/models/active_storage/blob.rb, line 205 def service_headers_for_direct_upload service.headers_for_direct_upload key, filename: filename, content_type: content_type, content_length: byte_size, checksum: checksum end
Возвращает Hash заголовков для service_url_for_direct_upload запросов.
# File activestorage/app/models/active_storage/blob.rb, line 200 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 end
Возвращает URL, который можно использовать для прямой загрузки файла для данного фрагмента данных на службе. Этот URL предназначен для кратковременного использования в целях безопасности и генерируется только по запросу со стороны JavaScript-кода на стороне клиента, отвечающего за загрузку.
# File activestorage/app/models/active_storage/blob.rb, line 146 def signed_id super(purpose: :blob_id) end
Возвращает подписанный идентификатор этого фрагмента данных, подходящий для ссылки на стороне клиента без опасений подделки.
# File activestorage/app/models/active_storage/blob.rb, line 182
def text?
content_type.start_with?("text")
end Возвращает true, если тип содержимого этого фрагмента данных относится к текстовому диапазону, например, text/plain.
# File activestorage/app/models/active_storage/blob.rb, line 232 def upload(io, identify: true) unfurl io, identify: identify upload_without_unfurling io end
Загружает io на службу в key для данного фрагмента данных. Фрагменты данных предназначены для неизменности, поэтому после загрузки файла в фрагмент данных этот метод вызывать не нужно. Если вам нужно создать производный фрагмент данных, вместо этого просто создайте новый фрагмент данных на основе старого.
Перед загрузкой мы вычисляем контрольную сумму, которая отправляется на службу для проверки целостности передачи. Если контрольная сумма не совпадает с той, что получает служба, будет вызвано исключение. Мы также измеряем размер io и сохраняем его в byte_size в записи фрагмента данных. Тип содержимого автоматически извлекается из io , если вы не указали content_type и не передали identify как false.
Обычно вызывать этот метод напрямую не нужно. Используйте метод класса create_and_upload! вместо этого. Если вы используете этот метод напрямую, убедитесь, что вы используете его на сохранённом Blob, в противном случае данные другого фрагмента данных могут быть перезаписаны на службе.
# File activestorage/app/models/active_storage/blob.rb, line 190
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 Возвращает URL фрагмента данных на службе. Это возвращает постоянный URL для общедоступных файлов и возвращает временный URL для частных файлов. Частные файлы подписаны и не предназначены для общего доступа. Вместо этого URL должен быть показан только как переадресация с устойчивого, возможно, аутентифицированного URL. Скрытие URL за переадресацией также позволяет изменять службы без обновления всех URL.
# File activestorage/app/models/active_storage/blob.rb, line 177
def video?
content_type.start_with?("video")
end Возвращает true, если тип содержимого этого фрагмента данных относится к видеодиапазону, например, video/mp4.
© 2004–2020 David Heinemeier Hansson
Licensed under the MIT License.