LoginSignup
2
1

Next.js+Rails製アプリケーションでCloudinaryへ画像をアップロードする方法

Last updated at Posted at 2021-05-16

概要

フロントエンド(Next.js)からバックエンド(Rails APIモード)にAPIを投げ、Cloudinaryへ画像をアップロードする。

リポジトリ

フロントエンド側(Next.js)

ImageUploadコンポーネント

import { useState } from "react";

export default function ImageUpload({ postId }) {
  const [image, setImage] = useState(null);

  const handleSubmit = async (e) => {
    e.preventDefault();

    const formData = new FormData();
    formData.append("files", image);
    formData.append("refId", postId); //Rails側でpostとeyecatchを紐づけるため
    formData.append("field", "image");

    const res = await fetch(`http://localhost:3000/api/v1/eyecatches/`, {
      method: "POST",
      body: formData,
    });

    if (res.ok) {
      alert("Image uploaded");
    }
  };

  const handleFileChange = (e) => {
    setImage(e.target.files[0]);
  };

  return (
      <form onSubmit={handleSubmit}>
        <input type="file" onChange={handleFileChange} />
        <input type="submit" value="Upload" />
      </form>
  );
}

バックエンド(Rails)

gemをインストール

gem 'cloudinary'
gem 'carrierwave'
bundle install

コントローラー

今回はeyecatches_controllerを用意した。

class Api::V1::EyecatchesController < ApplicationController
  def create
    res = Cloudinary::Uploader.upload(
      params[:files],
      :folder => "travellog",
      :public_id => "eyecatch_" + params[:refId], /* 画像に名前をつけている */
    )

    /* res['secure_url']には画像のパスが入っている */
    eyecatch = Eyecatch.new(post_id: params[:refId], image: res['secure_url'])

    if eyecatch.save
      render json: { status: :ok, data: eyecatch }
    else
      render json: { status: 500, data: eyecatch.errors }
    end
  end
end

routes.rb

ルーティングを設定

resources :eyecatches, only: [:create]

モデル

今回は、PostEyecatchを1対1で紐づけている。

rails g model Eyecatch image:text post_id:integer

アップローダー

EyecatchUploderを作成する。

rails g uploder EyecatchUploder
class EyecatchUploader < CarrierWave::Uploader::Base
  include Cloudinary::CarrierWave
  CarrierWave.configure do |config|
    config.cache_storage = :file
  end
end

config/cloudinary.yml

config/cloudinary.ymlでcloudinaryの必要情報を読み込む

development:
  cloud_name: <%= ENV[:CLOUDINARY_CLOUD_NAME] %>
  api_key: <%= ENV[:CLOUDINARY_API_KEY] %>
  api_secret: <%= ENV[:CLOUDINARY_API_SECRET] %>
  enhance_image_tag: true
  static_file_support: false
production:
  cloud_name: <%= ENV[:CLOUDINARY_CLOUD_NAME] %>
  api_key: <%= ENV[:CLOUDINARY_API_KEY] %>
  api_secret: <%= ENV[:CLOUDINARY_API_SECRET] %>
  enhance_image_tag: true
  static_file_support: true
test:
  cloud_name: <%= ENV[:CLOUDINARY_CLOUD_NAME] %>
  api_key: <%= ENV[:CLOUDINARY_API_KEY] %>
  api_secret: <%= ENV[:CLOUDINARY_API_SECRET] %>
  enhance_image_tag: true
  static_file_support: false

環境変数

今回は.envファイルを用意して環境変数を設定しました。

gem 'dotenv-rails'
bundle install
// クオーテーションは不要
CLOUDINARY_CLOUD_NAME = ***********
CLOUDINARY_API_KEY = ***********
CLOUDINARY_API_SECRET = ***********
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1