Работая над своим последним проектом в Flatiron School, я столкнулся с блокировщиком загрузки фотографий в свои профили пользователей в моем проекте. К счастью, я смог добиться сотрудничества с преступником, но не раньше, чем через пару дней детективной работы.

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

Настроить ActiveStorage на Rails

Active Storage - это функция Ruby on Rails, предназначенная для упрощения загрузки и извлечения файлов в облачных сервисах (таких как Amazon S3, Microsoft Azure Storage или Google Cloud Storage). Он заменяет функциональность таких драгоценных камней, как Paperclip и CarrierWave. Это также облегчает локальную обработку файлов во время разработки. Есть много ссылок на эту настройку, но я нашел Документацию по Edge Guides наиболее простой.

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

Сначала настройте свои базы данных для Active Storage. Вам понадобятся две дополнительные таблицы. Создайте файлы миграции, запустив

rails active_storage:install

Затем запустите миграции.

rails db:migrate

Проверьте свою службу в config / environment / development.rb. Для начала должно быть установлено значение "локальное".

config.active_storage.service = :local

Создать модель и контроллер

Я создал модель под названием Профиль, которая принадлежит пользователю. При миграции для профиля я включил столбец для хранения URL-адреса моего изображения.

class AddPhotoToProfiles < ActiveRecord::Migration[6.0]
  def change
    add_column :profiles, :photo, :string
  end
end

Теперь настройте вашу модель для обработки изображения. Добавьте в модель макрос has_one_attached.

class Profile < ApplicationRecord
  belongs_to :user
  has_one_attached :avatar
end

Вы ожидали, что profiles_controller.rb будет обрабатывать обновления, но я решил создать отдельный контроллер только для изображений.

rails g controller photos

Метод обновления photos_controller.rb должен выглядеть примерно так:

Этот контроллер предоставляет три варианта хранения данных фотографии: загруженный файл, данные изображения Base64 или другие.

Параметр Base64 требует, чтобы данные были преобразованы в объект StringIO. Кроме того, данные, полученные с камеры, содержат дополнительную информацию в начале строки, которая не нравится StringIO. Выглядит это примерно так:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA...

Взгляните на строку 11 метода обновления photos_controller.rb. Все, что находится до запятой, нужно убрать. Я удалил с помощью params [: camera] .split («,») [1].

Создайте компонент React с ‹input type =” file ”/›

Давайте посмотрим на внешний вид вещей. Я разделил свои фото действия. Загрузка файла осуществляется в компоненте React, содержащем форму профиля. Вход выглядит примерно так:

<input type="file" name="newPhoto"accept="image/png, image/jpeg" onChange={this.handleImageChange} />

Функция handleImageChange сохраняет данные файла в состоянии компонента.

Я загружаю только один файл, поэтому я ссылаюсь на e.target.files [0].

Другая функция обрабатывает загрузку, используя ключ «файл» в FormData.

Когда форма отправляется, функция handleSubmit вызывает uploadPhoto.

Создание компонента React с использованием данных камеры HTML5

Я создал отдельный компонент для обработки фотографий с веб-камеры. Чтобы сэкономить время, я использовал пакет react-html5-camera-photo.

yarn add react-html5-camera-photo

В моем компоненте React я импортировал соответствующие файлы.

import Camera from "react-html5-camera-photo";
import "react-html5-camera-photo/build/css/index.css";

Затем я реализовал компонент «Камера».

<Camera onTakePhoto={this.handlePhoto} isImageMirror={false} />

Функция handlePhoto сохраняет данные Base64 в состояние компонента.

Когда пользователь утверждает фотографию, нажимая кнопку «Сохранить», фотография загружается с функцией handleKeep с помощью клавиши «камера» в FormData.

Вот и все. Данные изображения теперь могут быть загружены либо в виде данных Base64, либо в виде файла. После того, как он будет протестирован и заработает, внедрить службу облачного хранилища просто: нужно настроить выбранный вами сервис и указать свои учетные данные в рельсах.

Я надеюсь, что мое решение поможет другим выполнить эту задачу в короткие сроки. Удачного кодирования!