Доброго времени суток, хабражители. Я бы хотел поделиться тем, как я решал проблему загрузки файлов на сервер и вывод изображений на страницах сайта, используя технологии Ruby on Rails, Rails Admin и Dragonfly. Кому интересно прошу под кат.

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

Изначально я рассматривал как вариант элементарную загрузку изображения на какой-либо image-hosting и оттуда напрямую добавлять полученные ссылки в поле для URL изображения в административной панели. Затем просто обрабатывая текущий обьект в цикле, забирать строку с URL адресом из добавленного в таблицу поля. И далее при помощи примитивного image_tag выводить его на странице, а в случае отсутствия поля вывод како-либо картинки-заглушки с сообщением о том, что изображение для данного товара отсутствует в базе.

Спустя некоторое время, я наткнулся на (как оказалаось позже) популярный гем под названием Dragonfly.
Вот что гласит описание на странице самого репозитория:

A Ruby gem for on-the-fly processing — suitable for image uploading in Rails, Sinatra and much more!


И вот сам линк на этот чудо-гем: dragonfly on github.

Я принялся изучать вики и документацию к гему, однако, даже следуя ей, ухитрился сделать пару ошибок. Но обо всем по порядку.

Как гласит нам инструкция на оф. сайте (сайт), мы должны добавить наш гем в Gemfile проекта.

gem 'dragonfly', "~>1.0.5"


И затем выполнить в терминале:

bundle install


Либо же можно уменшить количество комманд просто написав в терминале:

gem install dragonfly


Если Rails выдал заветный
Your bundle is complete!

То мы можем продолжать.

Введем следующую команду в терминале:

rails generate dragonfly


Она создаст файл конфигурации для Dragonfly. Сам файл будет лежать здесь: config/initializers/dragonfly.rb.

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

Так же мы должны создать поле для хранения адреса изображения в базе. Нам нужно создать новую миграцию и в ней описать добавление поля:

class AddImageUidToItem < ActiveRecord::Migration
  def change
    add_column :items, :image_uid, :string
  end
end


Items — это наша таблица с товарами.

Отдельного внимания заслуживает имя поля image_uid. Оно обязательно должно заканчиваться на _uid. По этому окончанию Dragonfly понимает что именно это поле ему и нужно. Вы можете задать свое имя поля с требуемым окончанием, но лично я не пробовал, так что думаю, лучше прислушаться к советам разработчиков.

Далее нужно указать аксессор для нашего изображения. Dragonfly имеет свой хелпер. Поэтому укажем именно его.

class Photo < ActiveRecord::Base
  dragonfly_accessor :image    # defines a reader/writer for image
  # ...
end


Dragonfly сам понимает что :image — это image_uid, поэтому в дальнейшем мы будем использовать именно image.

Теперь мы можем приступить непосредственно к фронтенду.

Rails Admin поддерживает работу как с Dragonfly, так и с другими загрузчиками, поэтому в нем уже есть конфигурационные файлы для них.

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

Далее нам нужно перегрузить сервер и зайти в администритивную часть.

Вот что мы должны увидеть возле нашего поля Image во время добавления/редактирования товара.



И вот что выйдет, если мы выберем файл.



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

А сейчас пора заняться выводом этого всего.

Вот как это реализовал я:

<% if item.image_stored? %>
    <%= image_tag item.image.url, height: 200 %>
<% else %>
    <%= image_tag 'no_image.png', height: 200 %>
<% end %>


В моем случае «no_image.png» — это та самая заглушка для отсутствуещего изображения, которая лежит в папке assets.

Вот как это выглядит на самой странице:



Спасибо всем, кто дочитал до конца мою статью.