Статьи

Rails Загрузка изображения с помощью Dragonfly

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

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

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

В этом уроке вы создадите простое приложение на Rails; Я назвал мой Dragon-Uploader. Приложение будет иметь только одну функцию: загрузка изображений.

Чтобы использовать стрекозу, вам нужно установить ImageMagick на вашем компьютере. Выполните любое из следующих действий, в зависимости от вашей операционной системы.

Пользователи Mac:

brew install imagemagick

Пользователи Ubuntu:

sudo apt-get install imagemagick

rails new dragon-uploader -T

Опция -T гарантирует, что ваше Rails-приложение будет создано без набора тестов по умолчанию.

Перейдите в свой Gemfile и добавьте драгоценный камень dragonfly .

1
2
3
#Gemfile
 
gem ‘dragonfly’, ‘~> 1.0’, ‘>= 1.0.12’

Не забудьте связать.

bundle install

Давайте сгенерируем наш контроллер.

rails generate controller Photos

Первым шагом к интеграции Dragonfly в ваше приложение Rails является запуск команды генерации dragonfly из вашего терминала.

rails generate dragonfly

Это создаст файл инициализатора для Dragonfly в вашей папке config/initializers .

Файл выглядит так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#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

1
2
3
4
5
#app/models/photo.rb
 
class Photo < ActiveRecord::Base
  dragonfly_accessor :image
end

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

Теперь перейдите к файлу миграции и добавьте столбцы.

01
02
03
04
05
06
07
08
09
10
11
12
#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 с необходимыми действиями для загрузки изображения. Это должно выглядеть так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#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

Вам нужно будет настроить ваши маршруты.

А пока добавьте маршруты к трем созданным вами действиям.

1
2
3
4
5
6
7
#config/routes.rb
 
Rails.application.routes.draw do
  resource :photos only: [:index, :new, :create]
 
  root to: «photos#index»
end

Вы должны настроить свои взгляды, как у меня ниже:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#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(‘100×100’).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?’
      </tr>
    <% end %>
  </tbody>
</table>
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
#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 предоставляет вам необходимые методы для этого в ваших инициализаторах.

1
2
3
4
5
6
7
#config/initializers/dragonfly.rb
 
# Add model functionality
if defined?(ActiveRecord::Base)
  ActiveRecord::Base.extend Dragonfly::Model
  ActiveRecord::Base.extend Dragonfly::Model::Validations
end

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
#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:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
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?
  validates_property :format, of: :image, as: ‘png’, if: :image_changed?
end

Вы можете прочитать больше об этом в документации по Dragonfly .

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#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
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#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 %>
01
02
03
04
05
06
07
08
09
10
11
12
13
#app/views/photos/show.html.erb
 
<div>
  <strong>Title:</strong>
  <%= @photo.title %>
</div>
<div>
  <strong>Image:</strong>
  <%= image_tag @photo.image.thumb(‘400×200#’).url if @photo.image_stored?
</div>
 
<%= link_to ‘Edit’, edit_photo_path(@photo) %> |
<%= link_to ‘Back’, photos_path %>

Если вы попытаетесь получить доступ к странице шоу или редактирования, вы увидите ошибки. Это связано с тем, что мы ограничили маршрут :new, :index, and :update . Теперь иди и измени это; это должно выглядеть так:

1
2
3
4
5
6
7
#config/routes.rb
 
Rails.application.routes.draw do
  resources :photos
 
  root to: «photos#index»
end

Теперь вы можете интегрировать Dragonfly в ваше Rails-приложение. Обязательно ознакомьтесь с документацией, если вы хотите попробовать больше функций, не упомянутых здесь. Надеюсь, вам понравилось.

Помните, что вы всегда можете добавить отзывы, вопросы и комментарии в форму ниже.