класс ActiveStorage::Blob
Объект blob — это запись, которая содержит метаданные о файле и ключ, указывающий, где этот файл находится на сервисе. Blobs можно создать двумя способами:
-
После того, как файл был загружен на сервер в службу через
create_after_upload!. -
До непосредственной загрузки файла на сервер со стороны клиента через
create_before_direct_upload!.
Первый вариант не требует интеграции с JavaScript на стороне клиента и может использоваться любым другим серверным сервисом, работающим с файлами. Второй вариант быстрее, так как вы не используете собственный сервер в качестве промежуточной точки для загрузки, и он может работать с развертываниями, такими как Heroku, которые не предоставляют больших объёмов дискового пространства.
Blobs предназначены для неизменности в отношении их ссылки на конкретный файл. Вы можете обновлять метаданные blob на последующем этапе, но не следует обновлять ключ или изменять загруженный файл. Если вам нужно создать производную или иным образом изменить blob, просто создайте новый blob и удалите старый.
Публичные методы класса
# File activestorage/app/models/active_storage/blob.rb, line 54
def build_after_upload(io:, filename:, content_type: nil, metadata: nil, identify: true)
new(filename: filename, content_type: content_type, metadata: metadata).tap do |blob|
blob.upload(io, identify: identify)
end
end Возвращает новый, несохранённый экземпляр blob после того, как io был загружен на сервер. При указании типа содержимого передайте identify: false, чтобы обойти автоматическое определение типа содержимого.
# File activestorage/app/models/active_storage/blob.rb, line 70 def create_after_upload!(io:, filename:, content_type: nil, metadata: nil, identify: true) build_after_upload(io: io, filename: filename, content_type: content_type, metadata: metadata, identify: identify).tap(&:save!) end
Возвращает сохранённый экземпляр blob после того, как io был загружен на сервер. Обратите внимание, что blob сначала создаётся, затем io загружается, а затем blob сохраняется. Это делается для того, чтобы избежать загрузки (что может занять время), при одновременном открытом транзакции базы данных. При указании типа содержимого передайте identify: false , чтобы обойти автоматическое определение типа содержимого.
# File activestorage/app/models/active_storage/blob.rb, line 79 def create_before_direct_upload!(filename:, byte_size:, checksum:, content_type: nil, metadata: nil) create! filename: filename, byte_size: byte_size, checksum: checksum, content_type: content_type, metadata: metadata end
Возвращает сохранённый blob без загрузки файла на сервер. Этот blob будет указывать на ключ, где пока нет файла. Он предназначен для совместного использования с загрузкой на стороне клиента, которая сначала создаст blob, чтобы получить подписанную URL-адрес для загрузки. Эта подписанная URL-адрес указывает на ключ, сгенерированный blob. После отправки формы с использованием прямой загрузки blob может быть связан с соответствующей записью с помощью подписанного идентификатора.
# File activestorage/app/models/active_storage/blob.rb, line 48 def find_signed(id) find ActiveStorage.verifier.verify(id, purpose: :blob_id) end
Вы можете использовать подписанный идентификатор blob для ссылки на него на стороне клиента без риска подделки. Это особенно полезно для прямых загрузок, когда клиентской стороне необходимо сослаться на blob, который был создан до самой загрузки при отправке формы.
Подписанный идентификатор также используется для создания стабильных URL-адресов для blob через BlobsController.
# File activestorage/app/models/active_storage/blob.rb, line 88 def generate_unique_secure_token SecureRandom.base36(28) end
Чтобы предотвратить проблемы с регистронезависимыми файловыми системами, особенно в сочетании с базами данных, которые обрабатывают индексы как регистрозависимые, все ключи blob, которые генерируются, будут содержать только алфавит символов базы-36 и, следовательно, будут строчными. Чтобы сохранить тот же или более высокий уровень энтропии, что и в кодировании base-58, используемом в `has_secure_token`, количество используемых байтов увеличивается до 28 с 24 стандартных.
Методы публичного экземпляра
# File activestorage/app/models/active_storage/blob.rb, line 121
def audio?
content_type.start_with?("audio")
end Возвращает true, если тип содержимого этого blob находится в диапазоне аудио, например, audio/mpeg.
# File activestorage/app/models/active_storage/blob.rb, line 214
def delete
service.delete(key)
service.delete_prefixed("variants/#{key}/") if image?
end Удаляет файлы на сервисе, связанные с blob. Это следует делать только в том случае, если blob также будет удален, или иначе у вас будет недействительная ссылка. В большинстве случаев рекомендуется использовать методы purge и purge_later.
# File activestorage/app/models/active_storage/blob.rb, line 188 def download(&block) service.download key, &block end
Загружает файл, связанный с этим blob. Если блок не задан, весь файл считывается в память и возвращается. Это потребует много оперативной памяти для очень больших файлов. Если блок задан, загрузка выполняется потоком и возвращается частями.
# File activestorage/app/models/active_storage/blob.rb, line 111 def filename ActiveStorage::Filename.new(self[:filename]) end
Возвращает экземпляр ActiveStorage::Filename имени файла, который можно запросить для получения имени файла без расширения, расширения и очищенной версии имени файла, пригодной для использования в URL-адресах.
# File activestorage/app/models/active_storage/blob.rb, line 116
def image?
content_type.start_with?("image")
end Возвращает true, если тип содержимого этого blob находится в диапазоне изображений, например, image/png.
# File activestorage/app/models/active_storage/blob.rb, line 103 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 end
Возвращает ключ, указывающий на файл на сервисе, связанный с этим blob. Ключ имеет формат secure-token от Rails в нижнем регистре. Например: xtapjjcjiudrlk3tmwyjgpuobabd. Этот ключ не предназначен для прямого отображения пользователю. Всегда ссылайтесь на blobs с помощью #signed_id или проверенной формы ключа.
# File activestorage/app/models/active_storage/blob.rb, line 205
def open(tmpdir: nil, &block)
service.open key, checksum: checksum,
name: [ "ActiveStorage-#{id}-", filename.extension_with_delimiter ], tmpdir: tmpdir, &block
end Загружает blob в временный файл на диске. Возвращает временный файл.
Имя временного файла начинается с ActiveStorage- и ID blob. Его расширение соответствует расширению blob.
По умолчанию временный файл создается в Dir.tmpdir. Передайте tmpdir: для создания его в другом каталоге:
blob.open(tmpdir: "/path/to/tmp") do |file| # ... end
Временный файл автоматически закрывается и удаляется после выполнения заданного блока.
Выбрасывает ActiveStorage::IntegrityError, если загруженные данные не соответствуют контрольной сумме blob.
# File activestorage/app/models/active_storage/blob.rb, line 222 def purge destroy delete rescue ActiveRecord::InvalidForeignKey end
Удаляет файл на сервисе и затем уничтожает запись blob. Это рекомендуемый способ удаления ненужных blob. Однако следует отметить, что удаление файла со службы инициирует HTTP-соединение со службой, что может быть медленным или невозможно, поэтому не используйте этот метод внутри транзакции или в обратных вызовах. Используйте purge_later вместо этого.
# File activestorage/app/models/active_storage/blob.rb, line 230 def purge_later ActiveStorage::PurgeJob.perform_later(self) end
Добавляет в очередь ActiveStorage::PurgeJob для вызова purge. Это рекомендуемый способ удаления blob из транзакции, обратного вызова Active Record или в любой другой ситуации реального времени.
# File activestorage/app/models/active_storage/blob.rb, line 154 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 140
def service_url(expires_in: ActiveStorage.service_urls_expire_in, disposition: :inline, filename: nil, **options)
filename = ActiveStorage::Filename.wrap(filename || self.filename)
service.url key, expires_in: expires_in, filename: filename, content_type: content_type_for_service_url,
disposition: forced_disposition_for_service_url || disposition, **options
end Возвращает URL-адрес blob на сервисе. Этот URL-адрес предназначен для кратковременного использования в целях безопасности и не должен использоваться напрямую с пользователями. Вместо этого service_url должен отображаться только в качестве перенаправления с постоянного, возможно, аутентифицированного URL-адреса. Скрытие service_url за перенаправлением также дает вам возможность изменять службы без обновления всех URL-адресов. И это позволяет кэшировать постоянные URL-адреса, которые перенаправляют на service_url в представлении.
# File activestorage/app/models/active_storage/blob.rb, line 149 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-адрес, который можно использовать для прямой загрузки файла для этого blob на службу. Этот URL-адрес предназначен для кратковременного использования в целях безопасности и генерируется только по требованию клиентской стороной JavaScript, отвечающей за загрузку.
# File activestorage/app/models/active_storage/blob.rb, line 95 def signed_id ActiveStorage.verifier.generate(id, purpose: :blob_id) end
Возвращает подписанный идентификатор этого blob, подходящий для использования на стороне клиента без опасений по поводу подделки. Он использует общефреймворковый верификатор на ActiveStorage.verifier, но с определенной целью.
# File activestorage/app/models/active_storage/blob.rb, line 131
def text?
content_type.start_with?("text")
end Возвращает true, если тип содержимого этого blob находится в диапазоне текста, например, text/plain.
# File activestorage/app/models/active_storage/blob.rb, line 170 def upload(io, identify: true) unfurl io, identify: identify upload_without_unfurling io end
Загружает io на службу на key для этого blob. Blob предназначены для неизменности, поэтому вам не следует использовать этот метод после того, как файл уже был загружен, чтобы соответствовать blob. Если вы хотите создать производный blob, вы должны вместо этого просто создать новый blob на основе старого.
Перед загрузкой мы вычисляем контрольную сумму, которая отправляется на службу для проверки целостности передачи. Если контрольная сумма не совпадает с полученной службой, будет выброшено исключение. Мы также измеряем размер io и сохраняем его в byte_size в записи blob. Тип содержимого автоматически извлекается из io, если не указан content_type и не передан identify как false.
Обычно вам не нужно вызывать этот метод напрямую. Используйте методы-фабрики классов build_after_upload и create_after_upload!.
# File activestorage/app/models/active_storage/blob.rb, line 126
def video?
content_type.start_with?("video")
end Возвращает true, если тип содержимого этого blob находится в диапазоне видео, например, video/mp4.
© 2004–2019 David Heinemeier Hansson
Licensed under the MIT License.