概要
フロントエンド(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]
モデル
今回は、Post
とEyecatch
を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 = ***********