У меня есть форма отправки пользователей, которая включает изображения. Первоначально я использовал 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-адрес новым один в моей базе данных.
Подводя итог, я хотел бы разрешить прямую загрузку в 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
Это просто идея. Если у меня возникнет проблема, я использую подписанный URL-адрес после изменения размера изображения в клиенте. — person Joe Morano schedule 19.08.2020
@ogelacinyc Как на самом деле получить подписанный URL? Это то, что я пытался сделать, но мне удалось вернуть только URL-адрес, который ведет к отсутствующему активу. — person Joe Morano schedule 19.08.2020
Я совершенно не знаю Active Storage. Тем не менее, хороший шаблон для вашего случая использования — изменять размер изображения, когда оно появляется. Для этого
Примечание. Вы можете использовать один и тот же сегмент Bucket (вместо Bucket1 и Bucket2), но событие для изменения размера изображения будет отправляться каждый раз, когда в этом сегменте создается файл. Вы можете использовать PubSub в качестве промежуточного программного обеспечения и добавить к нему фильтр, чтобы ваша функция запускалась только с файлом, созданным в правильной папке. Я написал об этом статью </ а>
Это отличная идея, но, читая документы, кажется, что я не могу использовать тот же URL-адрес для изображения с измененным размером, что проблематично, потому что я не знаю, как связать URL-адрес для изображения с измененным размером с моей базой данных. записывать. — person Joe Morano; 07.07.2020
Вот что я сделал, чтобы это исправить:
1- Я загружаю вложение, добавленное пользователем, непосредственно моему провайдеру услуг (я использую S3).
2- Я добавляю
after_commit
задание, которое вызываетSidekiq
воркера для генерации больших пальцев3- Мой работник sidekiq (
AttachmentWorker
) вызывает методgenerate_thumbs
моей модели4-
generate_thumbs
будет перебирать различные размеры, которые я хочу сгенерировать для этого файлаА теперь самое сложное:
В методе
file_url
мы вызовем.processed
, только если передадимprocess = true
. Я много экспериментировал с этим методом, чтобы добиться от него наилучшего результата..processed
проверит с вашей корзиной, существует ли файл или нет, а если нет, он сгенерирует ваш новый файл и загрузит его.Кроме того, вот еще один вопрос, который я ранее задавал относительно ActiveStorage, который также может вам помочь: ActiveStorage & S3: Сделать файлы общедоступными