Как сохранить место для хранения и время загрузки с помощью Active Storage?

У меня есть форма отправки пользователей, которая включает изображения. Первоначально я использовал Carrierwave, но при этом изображение отправляется на мой сервер для обработки перед сохранением в облачных службах Google, и если изображение / изображения слишком велико, время запроса истекает, и пользователь просто получает сервер ошибка.

Так что мне нужен способ загрузки напрямую в GCS. Active Storage казался идеальным решением, но я действительно не понимаю, насколько жестким кажется сжатие.

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

Следующим лучшим решением было бы создать вариант с измененным размером при загрузке, используя что-то вроде @record.images.first.variant(resize_to_limit [xxx,xxx]) #using image_processing gem, но в документации, похоже, подразумевается, что вариант может быть создан только при загрузке страницы, что, очевидно, будет чрезвычайно вредно для времени загрузки, особенно если изображений много. Еще одним доказательством этого является то, что когда я создаю вариант, его нет в моем ведре GCS, поэтому он явно существует только в памяти моего сервера. Если я попробую

@record.images.first.variant(resize_to_limit [xxx,xxx]).service_url

Я получаю обратно URL, но он недействителен. Я получаю неудачное изображение, когда пытаюсь отобразить изображение на моем сайте, и когда я посещаю URL-адрес, я получаю следующие ошибки от GCS:

Указанный ключ не существует. Нет такого объекта.

поэтому, по-видимому, я не могу создать постоянный URL-адрес.

Третьим лучшим решением было бы написать функцию Google Cloud, которая автоматически изменяет размер изображений внутри Google Cloud, но читая docs, похоже, мне придется создать новый файл измененного размера с новым URL-адресом, и я не уверен, как я могу заменить исходный URL-адрес новым один в моей базе данных.

См. также:  Rails 3 Application / User Settings - лучшая практика?

Подводя итог, я хотел бы разрешить прямую загрузку в GCS, но контролировать размер файлов до их загрузки пользователем. Мои проблемы с Active Storage заключаются в том, что (1) я не могу контролировать размер файлов в моем ведре GCS, что приводит к произвольным затратам на хранение, и (2) мне, по-видимому, приходится выбирать между пользователями, которые должны загружать произвольно большие файлы, или необходимость обрабатывать изображения во время загрузки страницы, что будет очень дорого с точки зрения затрат на сервер и времени загрузки.

Кажется чрезвычайно странным, что Active Storage было настроено таким образом, и я не могу не думать, что что-то упускаю. Кто-нибудь знает способ решить любую проблему?

На мой взгляд, сделайте дамп active_storage и используйте драгоценный камень святыни, который будет обрабатывать сильно настраиваемые производные параметры для вас. См. Здесь: shrinerb.com/docs/plugins/derivatives.   —  person Joe Morano    schedule 08.07.2020

@BKSpurgeon Попробовал, но документация по облачным сервисам Google, к сожалению, не существует.   —  person Joe Morano    schedule 15.08.2020

святыня не зависит от облаков. Для этого вам придется полагаться на сторонний гем: github.com/renchap/shrine-google_cloud_storage — он должен работать из коробки с (незначительными) модификациями, чтобы API соответствовал. Я на 99% уверен, что автор тоже использует производные. Я не могу представить, чтобы это заработало больше 20 минут.   —  person Joe Morano    schedule 15.08.2020

@BKSpurgeon Знаете ли вы о решении GCS для Uppy? К тому же, похоже, есть только документация по S3.   —  person Joe Morano    schedule 16.08.2020

uppy должен работать с apis Google с незначительными изменениями в образце кода святыни — мне удалось загрузить файлы в облачное хранилище Google с помощью uppy и shrine, но в моем конкретном случае использования я просто переключился на AWS, без особых проблем (учитывая мой конкретный вариант использования). Сказав это: потенциально это может стать камнем преткновения, если API AWS изменится — я не уверен, что команда uppy dev поддерживает Google в качестве высокого приоритета, и я не знаю, вмешалось ли сообщество с запросами на поддержку для поддержки GCS.   —  person Joe Morano    schedule 16.08.2020

См. также:  Обновите документ Firestore из облачной функции

Это просто идея. Если у меня возникнет проблема, я использую подписанный URL-адрес после изменения размера изображения в клиенте.   —  person Joe Morano    schedule 19.08.2020

@ogelacinyc Как на самом деле получить подписанный URL? Это то, что я пытался сделать, но мне удалось вернуть только URL-адрес, который ведет к отсутствующему активу.   —  person Joe Morano    schedule 19.08.2020

Понравилась статья? Поделиться с друзьями:
IT Шеф
Комментарии: 2
  1. Joe Morano

    Я совершенно не знаю Active Storage. Тем не менее, хороший шаблон для вашего случая использования — изменять размер изображения, когда оно появляется. Для этого

    • Разрешить пользователю сохранять изображение в Bucket1
    • Когда файл создается в Bucket1, запускается событие . Подключите функцию к этому событию
    • Cloud Functions изменяет размер изображения и сохраняет его в Bucket2.
    • Вы можете удалить изображение в Bucket1 в конце облачной функции, оставить его на несколько дней или переместить в более дешевое хранилище (чтобы сохранить исходное изображение в случае возникновения проблем). Для этих двух последних действий вы можете использовать Life Cycle, чтобы удалить или изменить класс хранилища. файлов.

    Примечание. Вы можете использовать один и тот же сегмент Bucket (вместо Bucket1 и Bucket2), но событие для изменения размера изображения будет отправляться каждый раз, когда в этом сегменте создается файл. Вы можете использовать PubSub в качестве промежуточного программного обеспечения и добавить к нему фильтр, чтобы ваша функция запускалась только с файлом, созданным в правильной папке. Я написал об этом статью </ а>

    Это отличная идея, но, читая документы, кажется, что я не могу использовать тот же URL-адрес для изображения с измененным размером, что проблематично, потому что я не знаю, как связать URL-адрес для изображения с измененным размером с моей базой данных. записывать. person Joe Morano; 07.07.2020

  2. Joe Morano

    Вот что я сделал, чтобы это исправить:

    1- Я загружаю вложение, добавленное пользователем, непосредственно моему провайдеру услуг (я использую S3).

    2- Я добавляю after_commit задание, которое вызывает Sidekiq воркера для генерации больших пальцев

    3- Мой работник sidekiq (AttachmentWorker) вызывает метод generate_thumbs моей модели

    4- generate_thumbs будет перебирать различные размеры, которые я хочу сгенерировать для этого файла

    А теперь самое сложное:

    def generate_thumbs
      [
        { resize: '300x300^', extent: '300x300', gravity: :center },
        { resize: '600>' }
      ].each do |size|
        self.file_url(size, true)
      end
    end
    
    def file_url(size, process = false)
      value = self.file # where file is my has_one_attached
      
      if size.nil?
        url = value
      else
        url = value.variant(size)
    
        if process
          url = url.processed
        end
      end
    
      return url.service_url
    end
    

    В методе file_url мы вызовем .processed, только если передадим process = true. Я много экспериментировал с этим методом, чтобы добиться от него наилучшего результата.

    .processed проверит с вашей корзиной, существует ли файл или нет, а если нет, он сгенерирует ваш новый файл и загрузит его.

    Кроме того, вот еще один вопрос, который я ранее задавал относительно ActiveStorage, который также может вам помочь: ActiveStorage & S3: Сделать файлы общедоступными

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: