Russian (Pусский) translation by Marat Amerov (you can also view the original English article)
Загрузка файлов - важный функционал в веб-приложениях. Помимо того, что пользователи могут загружать фотографии с профилями, использование функционала загрузки файлов этим не ограничивается. Я продемонстрировал вам, как добавлять загрузку файлов в ваше Rails приложение, используя различные гемы. Сегодня я покажу вам, как сделать то же самое с помощью Dragonfly.
Dragonfly - очень гибкий Ruby гем для обработки изображений и других вложений, который уже используется на тысячах веб-сайтов.
У Вас может быть задача добавления загрузку файлов в Rails приложение, и возможно Вы не захотите использовать другие гемы. Вы можете взять Dragonfly, и определенно, не пожалеть об этом.
В этом уроке Вы создадите простое Rails приложение ; Я назвал своё — Dragon-Uploader. Приложение будет иметь только один функционал: загрузка изображений.
Установка ImageMagick
Чтобы использовать Dragonfly, Вам необходимо установить ImageMagick на вашу систему. Следуйте инструкциям ниже, в зависимости от вашей операционной системы.
Для пользователей Mac:
brew install imagemagick
Для пользователей Ubuntu:
sudo apt-get install imagemagick
Создание Rails приложения
rails new dragon-uploader -T
Параметр -T
гарантирует, что ваше Rails приложение будет создано без стандартного набора тестов.
Перейдите в свой Gemfile
и добавьте гем dragonfly
.
#Gemfile gem 'dragonfly', '~> 1.0', '>= 1.0.12'
Не забудьте запустить бандлер.
bundle install
Давайте сгенерируем наш контроллер.
rails generate controller Photos
Интеграция Dragonfly
Первым шагом к интеграции Dragonfly в ваше Rails приложение является запуск команды генерации dragonfly с вашего терминала.
rails generate dragonfly
Это команда создаст файл инициализации для Dragonfly в папке config/initializers
.
Файл выглядит следующим образом:
#config/intializers/dragonfly.rb require 'dragonfly' # Configure Dragonfly.app.configure do plugin :imagemagick secret "e83b8affbf1c807c7788c07d27e70e79fb0459f8e2c4375b59e60a3da11631e5" url_format "/media/:job/:name" datastore :file, root_path: Rails.root.join('public/system/dragonfly', Rails.env), server_root: Rails.root.join('public') end # Logger Dragonfly.logger = Rails.logger # Mount as middleware Rails.application.middleware.use Dragonfly::Middleware # Add model functionality if defined?(ActiveRecord::Base) ActiveRecord::Base.extend Dragonfly::Model ActiveRecord::Base.extend Dragonfly::Model::Validations end
rails generate model Photo
#app/models/photo.rb class Photo < ActiveRecord::Base dragonfly_accessor :image end
Dragonfly предоставляет акцессор, который Вам нужно будет добавить в вашу модель. С помощью него Вы получите доступ к чтению записи изображения.
Теперь перейдите к вашему файлу миграции и добавьте столбцы.
#xxx_create_photos.rb class CreatePhotos < ActiveRecord::Migration def change create_table :photos do |t| t.string :image_uid t.string :title t.timestamps null: false end end end
Примечание: Если вы используете avatar
, а не image
, как я сделал выше, Вы должны изменить столбец на avatar_uid
.
Миграция базы данных:
rake db:migrate
Настройте свой PhotosController
с необходимыми экшенами для загрузки изображения. Он должен выглядеть так:
#app/controllers/photos_controller.rb class PhotosController < ApplicationController def index @photos = Photo.all end def new @photo = Photo.new end def create @photo = Photo.new(photo_params) if @photo.save redirect_to photos_path else render :new end end private def photo_params params.require(:photo).permit(:image, :title) end end
Вам нужно будет настроить маршруты.
Пока добавьте маршруты к трем экшенам, которые вы создали.
#config/routes.rb Rails.application.routes.draw do resource :photos only: [:index, :new, :create] root to: "photos#index" end
Вам нужно настроить представления, как показано ниже:
#app/views/photos/index.html.erb <h2>Photos</h2> <p id="notice"><%= notice %></p> <table> <thead> <tr> <th>Title</th> <th>Image</th> <th colspan="3"></th> </tr> </thead> <tbody> <% @photos.each do |photo| %> <tr> <td><%= photo.title %></td> <td><%= link_to image_tag(photo.image.thumb('100x100').url), photo.image.url %></td> <td><%= link_to 'Show', photo %></td> <td><%= link_to 'Edit', edit_photo_path(photo) %></td> <td><%= link_to 'Destroy', photo, method: :delete, data: { confirm: 'Are you sure?' } %></td> </tr> <% end %> </tbody> </table>
#app/views/photos/new.html.erb <%= form_for @photo do |f| %> <div> <%= f.label :title %> <%= f.text_field :title %> </div> <div> <%= f.label :image %> <%= f.file_field :image %> </div> <div> <%= f.submit :submit %> </div> <% end %>
Мы вернемся к этим представлениям позже.
Валидация
В целях безопасности, не стоит предоставлять своим пользователям привилегию загрузки файлов любого типа. Dragonfly предоставляет вам необходимые методы для этого в ваших инициализаторах.
#config/initializers/dragonfly.rb # Add model functionality if defined?(ActiveRecord::Base) ActiveRecord::Base.extend Dragonfly::Model ActiveRecord::Base.extend Dragonfly::Model::Validations end
Теперь отредактируйте модель Photo, чтобы она выглядела так, как показано ниже:
#app/models/photo.rb class Photo < ActiveRecord::Base dragonfly_accessor :image #title validation validates_presence_of :title #image validations validates_presence_of :image validates_size_of :image, maximum: 400.kilobytes, message: "should not be more than 400KB", if: :image_changed? validates_property :format, of: :image, in: ['jpeg', 'png', 'gif'], message: "the formats allowed are: .jpeg, .png, .gif", if: :image_changed? end
Вот полный список валидаторов, которые предлагает Dragonfly:
class Photo extend Dragonfly::Model::Validations validates_presence_of :image validates_size_of :image, maximum: 500.kilobytes # Check the file extension validates_property :ext, of: :image, as: 'jpg' # ..or.. validates_property :mime_type, of: :image, as: 'image/jpeg' # ..or actually analyse the format with imagemagick.. validates_property :format, of: :image, in: ['jpeg', 'png', 'gif'] validates_property :width, of: :image, in: (0..400), message: "é demais cara!" # ..or you might want to use image_changed? method.. validates_property :format, of: :image, as: 'png', if: :image_changed? end
Вы можете больше узнать об этом в документации Dragonfly.
Вы также должны рассмотреть возможность предоставления пользователям возможности редактировать свои сохраненные изображения. Для этого нам нужно добавить два экшена в наш PhotosController
и создать страницу редактирования в наших представлениях. Возможно, Вы захотите добавить экшены «delete» и «show», пока Вы находитесь в контроллере:
#app/controllers/photos_controller.rb class PhotosController < ApplicationController before_action :set_photos, only: [:show, :edit, :update, :destroy] def index @photos = Photo.all end def new @photo = Photo.new end def create @photo = Photo.new(photo_params) if @photo.save redirect_to @photo else render :new end end def show end def edit end def update if @photo.update(photo_params) redirect_to @photo, notice: "photo successfully updated" else render :edit end end def destroy @photo.destroy redirect_to photos_url, notice: 'photo was successfully destroyed.' end private def photo_params params.require(:photo).permit(:image, :title) end def set_photos @photo = Photo.find(params[:id]) end end
#app/views/photos/edit.html.erb <%= form_for @photo do |f| %> <% if @photo.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(@photo.errors.count, "error") %> prohibited this photo from being saved:</h2> <ul> <% @photo.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <% end %> <div> <%= f.label :title %> <%= f.text_field :title %> </div> <div> <%= f.label :image %> <%= f.file_field :image %> </div> <div> <%= f.submit :submit %> </div> <% end %> <%= link_to "Show", @photo %> | <%= link_to "Back", photos_path %>
#app/views/photos/show.html.erb <div> <strong>Title:</strong> <%= @photo.title %> </div> <div> <strong>Image:</strong> <%= image_tag @photo.image.thumb('400x200#').url if @photo.image_stored? %> </div> <%= link_to 'Edit', edit_photo_path(@photo) %> | <%= link_to 'Back', photos_path %>
Если вы попытаетесь открыть страницу show или edit, вам будут показаны ошибки. Это связано с тем, что мы ограничили маршрут следующим: new,: index и: update
. Теперь его нужно изменить; Он должен выглядеть следующим образом:
#config/routes.rb Rails.application.routes.draw do resources :photos root to: "photos#index" end
Заключение
At this point, you can now integrate Dragonfly into your Rails application. Be sure to check out the documentation if you want to try more features not mentioned here. I hope you enjoyed it.
Remember, you can always add feedback, questions, and comments in the form below.
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post