Статьи

Загрузка изображений Rails: Использование Paperclip в приложении Rails

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

Скрепка — это рубиновый драгоценный камень, предоставляемый thinkbot. Он был создан, чтобы сделать прикрепление файла очень простым. В этом уроке вы увидите, как использовать Paperclip вместе с Devise.

Без долгих разговоров, давайте будем заняты.

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

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

brew install imagemagick

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

sudo apt-get install imagemagick

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

rails new paperclip

Откройте свой Gemfile и добавьте необходимые драгоценные камни:

gem 'paperclip'

gem 'devise'

Запустите пакетную установку, когда закончите.

С вашего терминала установите devise с помощью команды ниже:

rails generate devise:install

Когда это будет сделано, теперь вы можете сгенерировать свою модель User:

rails generate devise User

Перенесите вашу базу данных после.

rake db:migrate

Создайте свое мнение об изобретении.

rails generate devise:views

Используя ваш текстовый редактор, перейдите в app/views/layouts/application.html.erb и добавьте следующий код чуть выше блока yield .

1
2
3
4
#app/views/layouts/application.html.erb
 
<p class=»notice»><%= notice %></p>
<p class=»alert»><%= alert %></p>

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

Откройте app/controllers/application_controller.rb и вставьте следующие строки кода.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
#app/controllers/application_controller.rb
 
class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
 
  protect_from_forgery with: :exception
   
  before_action :configure_permitted_parameters, if: :devise_controller?
 
  protected
 
  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) { |u|
    devise_parameter_sanitizer.for(:account_update) { |u|
  end
end

Откройте свою модель User и сделайте так, чтобы она выглядела так:

01
02
03
04
05
06
07
08
09
10
11
#app/models/user.rb
 
class User < ActiveRecord::Base
  # Include default devise modules.
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
 
  has_attached_file :avatar, styles: { medium: «300×300», thumb: «100×100» }
  validates_attachment_content_type :avatar, content_type: /\Aimage\/.*\Z/
end

Вам нужно добавить колонку avatar в таблицу пользователей. Существует команда rails, которая делает это возможным с вашего терминала.

rails generate migration add_avatar_to_users

Это создаст новую миграцию в db/migrate . Откройте его и вставьте следующий код:

1
2
3
4
5
6
7
8
9
class AddAvatarToUsers < ActiveRecord::Migration
  def up
    add_attachment :users, :avatar
  end
 
  def down
    remove_attachment :users, :avatar
  end
end

Запустите вашу миграцию

rake db:migrate

Вы отредактируете свою регистрационную новую форму app/views/devise/registrations/new.html.erb и отредактируете форму app/views/devise/registrations/edit.html.erb ниже:

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
#app/views/devise/registrations/new.html.erb
 
<h2>Sign up</h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { multipart: true }) do |f|
  <%= devise_error_messages!
  <div class=»field»>
    <%= f.label :email %><br />
    <%= f.email_field :email, autofocus: true %>
  </div>
 
  <div class=»field»>
    <%= f.label :password %>
    <% if @minimum_password_length %>
    <em>(<%= @minimum_password_length %> characters minimum)</em>
    <% end %><br />
    <%= f.password_field :password, autocomplete: «off» %>
  </div>
 
  <div class=»field»>
    <%= f.label :password_confirmation %><br />
    <%= f.password_field :password_confirmation, autocomplete: «off» %>
  </div>
 
  <div class=»field»>
    <%= f.file_field :avatar %>
  </div>
 
  <div class=»actions»>
    <%= f.submit «Sign up» %>
  </div>
<% end %>
 
<%= render «devise/shared/links» %>
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
#app/views/devise/registrations/edit.html.erb
 
<h2>Edit <%= resource_name.to_s.humanize %></h2>
 
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f|
  <%= devise_error_messages!
 
  <div class=»field»>
    <%= f.label :email %><br />
    <%= f.email_field :email, autofocus: true %>
  </div>
 
  <% if devise_mapping.confirmable?
    <div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
  <% end %>
 
  <div class=»field»>
    <%= f.label :password %> <i>(leave blank if you don’t want to change it)</i><br />
    <%= f.password_field :password, autocomplete: «off» %>
  </div>
 
  <div class=»field»>
    <%= f.label :password_confirmation %><br />
    <%= f.password_field :password_confirmation, autocomplete: «off» %>
  </div>
 
  <div class=»field»>
    <%= f.file_field :avatar %>
  </div>
 
  <div class=»field»>
    <%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
    <%= f.password_field :current_password, autocomplete: «off» %>
  </div>
 
  <div class=»actions»>
    <%= f.submit «Update» %>
  </div>
<% end %>
 
<h3>Cancel my account</h3>
 
<p>Unhappy?
 
<%= link_to «Back», :back %>

Запустите браузер и проверьте, что у вас есть.

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

Откройте файл редактирования регистрации и сделайте так:

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
#app/views/devise/registrations/edit.html.erb
 
<h2>Edit <%= resource_name.to_s.humanize %></h2>
 
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f|
  <%= devise_error_messages!
 
  <div class=»field»>
    <%= f.label :email %><br />
    <%= f.email_field :email, autofocus: true %>
  </div>
 
  <% if devise_mapping.confirmable?
    <div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
  <% end %>
 
  <div class=»field»>
    <%= f.label :password %> <i>(leave blank if you don’t want to change it)</i><br />
    <%= f.password_field :password, autocomplete: «off» %>
  </div>
 
  <div class=»field»>
    <%= f.label :password_confirmation %><br />
    <%= f.password_field :password_confirmation, autocomplete: «off» %>
  </div>
 
  <div class=»field»>
    <%= f.file_field :avatar %>
 
    <% if @user.avatar?
      <%= image_tag @user.avatar.url(:thumb) %>
    <% end %>
  </div>
 
  <div class=»field»>
    <%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
    <%= f.password_field :current_password, autocomplete: «off» %>
  </div>
 
  <div class=»actions»>
    <%= f.submit «Update» %>
  </div>
<% end %>
 
<h3>Cancel my account</h3>
 
<p>Unhappy?
 
<%= link_to «Back», :back %>

Вы видите, что изменилось?

В приведенном выше коде есть условный оператор для проверки, существует ли уже аватар для пользователя, использующего строку <% if @user.avatar? %> <% if @user.avatar? %> . Если это возвращает true, следующая строка запускается, иначе это не так.

Проверка всегда важна при включении загрузки функций в ваше веб-приложение. Скрепка поставляется с мерами для обеспечения безопасности вашего приложения.

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

1
2
3
4
5
6
7
8
9
class User < ActiveRecord::Base
  has_attached_file :avatar
  # Validate content type
  validates_attachment_content_type :avatar, content_type: /\Aimage/
  # Validate filename
  validates_attachment_file_name :avatar, matches: [/png\Z/, /jpe?g\Z/]
  # Explicitly do not validate
  do_not_validate_attachment_file_type :avatar
end

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

Чтобы изучить другие функции, не описанные в этом руководстве, перейдите на страницу GitHub Paperclip .