Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Ruby on Rails
Code

Загрузка файлов в Rails вместе c Paperclip

by
Length:MediumLanguages:

Russian (Pусский) translation by Marat Amerov (you can also view the original English article)

Это последняя статья в серии «Загрузка с Rails». В последние несколько месяцев мы уже разбирали Shrine, Dragonfly и Carrierwave гемы. Сегодня наш гость это – Paperclip от Thoughtbot, компании, которая разрабатывает гемы, такие как FactoryGirl и Bourbon.

Paperclip, вероятно, самое популярное решение для управления вложениями  для Rails (более чем 13 миллионов загрузок) и по уважительной причине: он имеет много возможностей, большое сообщество и хорошею документацию. Так что надеюсь, вы готов, чтобы узнать больше об этом геме!

В этой статье вы узнаете как:

  • Подготовить Paperclip к установке
  • Интегрировать Paperclip в Rails
  • Добавить валидацию для вложений
  • Создать превью и обрабатывать  изображения
  • Скрыть URL-адреса
  • Хранить вложения на Amazon S3
  • Обезопасить работу с файлами в облаке, путем добавления логики авторизации

Исходный код из этой статьи доступен на GitHub.

Подготовка

Прежде чем мы углубимся в код, давайте сначала обсудим некоторые предостережения, которые вам следует знать для того, чтобы успешно работать с Paperclip:

  • Последняя версия Paperclip поддерживает Rails 4.2 + и Ruby 2.1 +. Этот гем может также использоваться без Rails.
  • ImageMagick должен быть установлен на вашем ПК (он доступен для всех основных платформ), и Paperclip должен иметь доступа к нему.
  • команда file должна быть доступна из командной строки. Для Windows она станет доступна после установки Development Kit, так что следуйте этим инструкциям, если у вас не установлен DevKit.

Когда вы будете готовы, создайте новое Rails приложение (я буду использовать Rails 5.0.2) без тестов по умолчанию:

Интеграция Paperclip

Добавьте Paperclip в Gemfile:

Gemfile

Установите его:

Предположим, что мы создаем приложение bookshelf, которое представляет собой список книг. Каждая книга будет иметь заголовок, описание, имя автора и обложку. Для начала, создадим и прогоним следующие миграции:

Обратите внимание на тип attachment, который представил для нас Paperclip. Под капотом, он создает четыре поля для нас:

  • image_file_name
  • image_file_size
  • image_content_type
  • image_updated_at

В отличие от Shrine и Carrierwave  Paperclip не имеет отдельный файл с конфигурациями. Все параметры определяются внутри модели, с помощью метода has_attached_file, поэтому его нужно добавить:

models/book.rb

Прежде чем перейти к основной части, давайте также создать контроллер нужными вьюхами и роутингом.

Создание контроллера, вьюхи и роутинга

Наш контроллер будет очень простой:

books_controller.rb

Вьюха index и паршал:

views/books/index.html.erb

views/books/_book.html.erb

Итоговые маршруты:

config/routes.rb

Отлично! Теперь давайте перейдем к основной части кода экшена new и формы.

Загрузка файлов

В общем, делать закачки с помощью Paperclip легко. Вам нужно только добавить соответствующий атрибут в permit (в нашем случае это атрибут image, и мы уже это сделали) и добавить поле для  файла в форме. Давай сделаем это сейчас:

views/books/new.html.erb

views/books/_form.html.erb

С этим кодом, вы уже можете начать загружать файлы. Подходящий этап, чтобы добавить валидацию.

Добавление валидации

Валадация в Paperclip может быть написана с использованием старых версий валидаторов, как validates_attachment_presence и validates_attachment_content_type или используя метод validates_attachment для определения сразу нескольких правил. Давайте придерживаться второго варианта:

models/book.rb

Как вы можете видеть, код очень прост. Мы требуем файл изображения меньше, чем 1 мегабайт. Обратите внимание, что если валидация не пройдет, то пост-обработка не будет выполнена. Paperclip так же имеет сообщения валидации для английского языка. Если вы хотите добавить  другие языки, подключите paperclip-i18n в ваш Gemfile.

Еще одна важная вещь, о которой следует упомянуть, заключается в том, что Paperclip требует, чтобы вы проверяли тип содержимого или имена файлов всех вложений, иначе возникнет исключение. Если вы на 100% уверены, что вам не нужны такие проверки (что является редким случаем), используйте do_not_validate_attachment_file_type, чтобы явно указать, какие поля не должны валидироваться.

Добавив валидацию, давайте также выведим сообщения об ошибках в нашей форме:

views/shared/_errors.html.erb

views/books/_form.html.erb

Отображение изображений

Итак, теперь загруженные изображения должны как-нибудь отображаться. Это делается с помощью хелпера image_tag и метода url. Теперь нужно создать вьюху для show:

views/books/show.html.erb

Мы выводим изображения, только если они действительно есть на диске. Кроме того если вы используете облачное хранилище, Paperclip выполняет запрос и проверяет существование файла. Конечно, эта операция может занять некоторое время, так что стоит рассмотреть использование методов present? или file?: они просто будут проверять, что поле image_file_name присутствует.

Обфускация URI

По умолчанию все файлы хранятся в папке public/system, так что, вы вероятно захотите её из системы контроля версий:

.gitignore

Однако, отображение полного URI файла, не всегда может быть хорошей идеей, и вам может понадобиться как-то скрыть ее. Самый простой способ включить обфускацию, для этого есть два параметра для метода has_attached_file:

models/book.rb

Правильные значения будут подставлены в url автоматически. hash_secret это обязательное поле, а самый простой способ его генерации - использовать:

Работа со стилями

Во многих случаях предпочтительно отображение эскизов изображений с предопределенными параметрами ширины и высоты, чтобы сохранить пропускную способность. Paperclip решает эту проблему с помощью стилей: каждый стиль имеет имя и набор правил, такие как размер, формат, качество и т.д.

Предположим, что мы хотим работать с исходным изображением и его эскизами, конвертируя  в формат JPEG. Эскиз должен обрезаться с параметрами 300x300px:

models/book.rb

# это  параметры геометрии, означающие: «При необходимости обрезать, сохраняя пропорции».

Мы также можем предоставить дополнительные параметры конверсии для каждого стиля. Например, давайте обеспечим 70% качества для больших эскизов при удалении всех метаданных и 90% качества исходного изображения, чтобы сделать его немного меньше:

models/book.rb

Отлично! Теперь отобразим миниатюры и укажем ссылку на исходное изображение:

views/books/show.html.erb

Обратите внимание, что в отличие от Carrierwave, Paperclip не позволяет вам писать @ book.image.thumb.url.

Если по какой-либо причине вы хотите вручную обновить загруженные изображения, вы можете использовать следующие команды для обновления только эскизов, добавления отсутствующих стилей или обновления всех изображений:

  • rake paperclip:refresh:thumbnails CLASS=Book
  • rake paperclip:refresh:missing_styles CLASS=Book
  • rake paperclip:refresh CLASS=Book

Хранение файлов в облаке

Как и все подобные решения, Paperclip позволяет загружать файлы в облако. Из коробки у него есть поддержка адаптеров S3 и Fog, но есть и сторонние драгоценные гемы для Azure и Dropbox. В этом разделе я покажу вам, как интегрировать Paperclip с Amazon S3. Сначала рассмотрим гем aws-sdk:

Установка:

Затем, нужно передать  параметры методу has_attached_file:

models/book.rb

Здесь я использую гем dotenv-rails, чтобы установить переменные окружения. Вы можете предоставить все значения непосредственно внутри модели, но не делать их общедоступными.

Интересно, что s3_credentials также принимает путь к YAML файлу, содержащему ваши ключи и имя bucket'а. Кроме того, вы можете установить различные значения для различных окружений:

Теперь все загруженные файлы будут загружаться в ваш S3 bucket.

Обеспечение безопасности при работе с облаком

Предположим, что вы не хотите, чтобы ваши загруженные файлы были доступны всем. По умолчанию все загрузки в облако отмечены как общедоступные, что означает, что любой может открыть файл по прямой ссылке. Если вы хотите ввести некоторую логику авторизации и проверки, того, кто может просматривать файл, установите для опции s3_permissions значение :private так:

Однако, теперь никто кроме вас, не сможет получить доступ к файлам. Поэтому давайте добавим новый экшен download в BooksController:

books_controller.rb

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

Не забудьте установить маршрут для объекта:

config/routes.rb

Хелпер должен использоваться следующим образом:

Заключение

Мы подошли к концу статьи! Сегодня мы познакомились с Paperclip, решение для управления вложениями для Rails, в действии и обсудили его основные возможности. Есть гораздо больше возможностей, поэтому обязательно просмотрите его документацию.

Кроме того, я рекомендую посетить wiki-страницу Paperclip, так как она представляет список туториалов, а также ссылки на сторонние гемы, поддерживающие Azure и Cloudinary, и позволяющие вам легко минимизировать загруженные файлы.

Спасибо, что оставались со мной все это время, и скоро увидимся!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.