Статьи

Разрешить загрузку файлов с помощью Rails и Refile

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

Они включают:

В этом уроке мы узнаем, как включить загрузку изображений в Rails с помощью Refile . Как написано на странице github в Refile , это современная библиотека для загрузки файлов для приложений Ruby. Это просто, но мощно.

Для любопытных, читающих это, вы, возможно, захотите узнать, что делает Refile лучше … Я просто сказал, что это так? Во всяком случае, это решать вам. 🙂

Особенности Refile включают в себя:

  • Настраиваемые бэкэнды, файловая система, S3 и т. Д.
  • Удобная интеграция с ORM.
  • На лету манипулирование изображениями и другими файлами.
  • Потоковый ввод-вывод для быстрой и удобной загрузки памяти.
  • Работает при повторном отображении формы, т. Е. При сбое проверки, даже на S3.
  • Прямые загрузки без усилий, даже на S3.
  • Поддержка нескольких загрузок.

Так что ты думаешь? Вы хотите дать ему шанс?

if "answer" = "yes" hop_on_board_with_me else still_tag_along end 

Давай катимся!

Установка приложений Rails

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

Создайте новое приложение Rails под названием photobook :

 rails new photobook 

Давайте создадим леса для нашего приложения:

 rails g scaffold Photo name:string 

Далее мы применяем нашу миграцию:

 rake db:migrate 

Интеграция Refile

Откройте свой Gemfile и добавьте его:

 #Gemfile gem 'refile', require: 'refile/rails' gem 'refile-mini_magick' 

Установите драгоценные камни, которые вы только что добавили:

 bundle install 

refile-mini_magick предназначен для обработки изображений. Вам необходимо установить ImageMagick в вашей системе.

В зависимости от вашей системы вы можете установить ImageMagick следующим образом:

 brew install imagemagick # OS X sudo apt-get install imagemagick # Ubuntu 

После этого добавьте метод attach для использования Refile в вашей модели:

 #app/models/photo.rb class Photo < ActiveRecord::Base attachment :profile_image end 

Давайте сгенерируем новую миграцию, чтобы добавить новый столбец для profile_image в нашу таблицу photos :

 rails generate migration add_profile_image_to_photos profile_image_id:string rake db:migrate 

Нам нужно установить photos_controller параметры, чтобы позволить profile_image в нашем photos_controller :

 #app/controllers/photos_controller.rb def photo_params params.require(:photo).permit(:name, :profile_image) end 

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

 #app/views/_form.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 class="field"> <%= f.label :name %><br> <%= f.text_field :name %> </div> <div> <%= f.attachment_field :profile_image %> </div> <div class="actions"> <%= f.submit %> </div> <% end %> 

Чтобы показать файл в ваших представлениях, отредактируйте ваш индекс и покажите страницу так:

 #app/views/index.html.erb <p id="notice"><%= notice %></p> <h1>Listing Photos</h1> <table> <thead> <tr> <th>Name</th> <th colspan="3"></th> </tr> </thead> <tbody> <% @photos.each do |photo| %> <tr> <td><%= photo.name %></td> <td><%= image_tag(attachment_url(photo, :profile_image, :fill, 100, 100)) %></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> <br> <%= link_to 'New Photo', new_photo_path %> #app/views/show.html.erb <p id="notice"><%= notice %></p> <p> <strong>Name:</strong> <%= @photo.name %> <%= image_tag attachment_url(@photo, :profile_image, :fill, 100, 100, format: "jpg") %> </p> <%= link_to 'Edit', edit_photo_path(@photo) %> | <%= link_to 'Back', photos_path %> 

Удаление вложений

Вы можете удалить старое изображение и добавить новое. Refile имеет функциональность, чтобы помочь в этом сценарии. Он добавляет атрибут к вашей модели при использовании метода attachment , который предназначен для использования с флажком в форме.

Вот как это сделать:

 #app/views/photo/_form.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 class="field"> <%= f.label :name %><br> <%= f.text_field :name %> </div> <div> <%= f.label :profile_image %> <%= f.attachment_field :profile_image %> <% if @photo.profile_image_id? %> <%= image_tag attachment_url(@photo, :profile_image, :fill, 100, 100, format: "jpg") %> <%= f.checkbox :remove_profile_image %> <%= f.label :remove_profile_image %> <% end %> </div> <div class="actions"> <%= f.submit %> </div> <% end %> 

В приведенном выше коде мы используем флажок, чтобы выбрать вариант удаления изображения. Мы не хотим, чтобы флажок отображался, когда ни одно изображение не было загружено, поэтому мы используем оператор if чтобы проверить наличие profile_image_id . Если оно есть, отображается изображение профиля и возможность его удаления. Это придает нашему приложению профессиональный вид. 🙂

Чтобы опция удаления работала, нам нужно сделать whilelist :remove_profile_image в сильных параметрах. Так что перейдите к вашему photos_controller и добавьте :remove_profile_image .

Вот как должен выглядеть ваш контроллер:

 #app/controllers/photos_controller.rb class PhotosController < ApplicationController before_action :set_photo, only: [:show, :edit, :update, :destroy] # GET /photos # GET /photos.json def index @photos = Photo.all end # GET /photos/1 # GET /photos/1.json def show end # GET /photos/new def new @photo = Photo.new end # GET /photos/1/edit def edit end # POST /photos # POST /photos.json def create @photo = Photo.new(photo_params) respond_to do |format| if @photo.save format.html { redirect_to @photo, notice: 'Photo was successfully created.' } format.json { render :show, status: :created, location: @photo } else format.html { render :new } format.json { render json: @photo.errors, status: :unprocessable_entity } end end end # PATCH/PUT /photos/1 # PATCH/PUT /photos/1.json def update respond_to do |format| if @photo.update(photo_params) format.html { redirect_to @photo, notice: 'Photo was successfully updated.' } format.json { render :show, status: :ok, location: @photo } else format.html { render :edit } format.json { render json: @photo.errors, status: :unprocessable_entity } end end end # DELETE /photos/1 # DELETE /photos/1.json def destroy @photo.destroy respond_to do |format| format.html { redirect_to photos_url, notice: 'Photo was successfully destroyed.' } format.json { head :no_content } end end private # Use callbacks to share common setup or constraints between actions. def set_photo @photo = Photo.find(params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. def photo_params params.require(:photo).permit(:name, :profile_image, :remove_profile_image) end end 

Проверка типа файла

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

Чтобы включить это, откройте вашу модель и добавьте редактировать строку метода attachment :

 #app/models/photo.rb attachment :profile_image, content_type: "image/jpeg" 

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

 #app/models/photo.rb attachment :profile_image, content_type: ["image/jpeg", "image/png", "image/gif"] 

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

 #app/models/photo.rb attachment :profile_image, type: image 

Это будет работать!

Вывод

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