Rails API + Reactで画像プレビュー機能を作る(Rails編)
この記事の目的
Rails APIとReactを使ったSPAアプリの画像プレビュー機能を解説していきたいと思います。
イメージはサムネの感じです。
画像プレビュー機能というのは、React側で実装するFormの中で画像ファイルを指定したら画面にその画像が表示されるというものです。
そして、投稿、画像アップロードするところまで解説したいと思います。
Rails APIとReactを使った画像アップロードも結構ややこしい部分があるのでわかりやすく解説したいと思います。
今回はRails API編です。ReactのFormから画像をアップロードするまでの実装を解説します。
開発環境
Ruby 2.6.6
Rails 6.1.4
開発手順
画像アップロードをするためのRails APIの開発手順は以下のようになります。
プロジェクト作成
任意のディレクトリ上でおなじみのrails newコマンドをapiモードで実行しましょう。
$ rails new api --api
モデル作成
画像をアップロードするためのモデルを作成していきましょう。
今回は画像だけでなく投稿という形でPostモデルを作成します。
$ rails g model Post content:text image:string
マイグレーションファイルはこんな感じになります。
db/migrate/日付_create_posts.rb
class CreatePosts < ActiveRecord::Migration[6.1]
def change
create_table :posts do |t|
t.text :content
t.string :image
t.timestamps
end
end
end
このままテーブルを作成しましょう。
以下のコマンドを実行しないとテーブルが作成されないので忘れないようにしましょう。
$ rails db:migrate
これで、テーブルが作成されました。
db/schema.rb
ActiveRecord::Schema.define(version: 2022_01_02_160457) do
create_table "posts", force: :cascade do |t|
t.text "content"
t.string "image"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
end
コントローラー作成
次にpostsコントローラーを作成して、APIコントローラーを作りましょう。
まずは以下のコマンドでコントローラーファイルを作成します。
$ rails g controller api/v1/posts
今回の目的は画像アップロードをして、画面に一覧表示することなのでcreateとindexのアクションのみ作ろうと思います。
以下のように記述していきましょう。
ここでは詳しくは解説しませんが、indexアクションで、投稿一覧を、createアクションでpostsテーブルのcontentカラムとimageカラムの投稿作成をAPI通信で設定しています。
app/controllers/api/v1/posts_controller.rb
class Api::V1::PostsController < ApplicationController
def index
posts = Post.all.order(created_at: :desc)
render json: posts
end
def create
post = Post.new(post_params)
if post.save
render json: post
else
render json: post.errors, status: 422
end
end
private
def post_params
params.require(:post).permit(:content, :image)
end
end
ルーティング設定
作ったコントローラーを基にルーティング設定しましょう。
postsコントローラーのindexアクションとcreateアクションのみをresourcesで設定していきます。
config/routes.rb
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
resources :posts, only: [:create, :index]
end
end
end
API通信設定
次にAPI通信を設定してReactからの通信を可能にしましょう。
まずはGemfileにコメントで記述されているgem 'rack-cors'のコメントを外します。
このgemによってAPI通信設定のcors.rbを使うことができます。
Gemfile
gem 'rack-cors'
$ bundle install
これでgemが追加できたので、cors.rbでAPI設定をしていきましょう。
config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins 'localhost:3000'
resource '*',
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head]
end
end
ここでoriginsにlocalhost:3000を設定しているのはReactのポート番号を設定しています。
今回はReactの3000番のポート番号を設定して、localhost:3000からの通信を許可するのでこのように設定しています。
画像アップロード設定
Railsの設定の最後に画像アップロード設定をしましょう。
まずは、画像アップロードのためのgemを追加しましょう。
画像アップロードのためのgemは'carrierwave'なので以下のようにGemfileに設定して追加していきます。
Gemfile
gem 'carrierwave'
$ bundle install
これで画像アップロードのgemが追加できたので、postsテーブルのimageカラムをuploaderに追加する設定をしていきます。
まずアップローダーの作成をします。
$ rails g uploader Image
作成された「app/uploaders/image_uploader.rb」の中に画像アップロードの設定をしていきます。
app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
# 画像ファイルがRailsアプリに保存される
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# 受け付け可能なファイルの拡張子を指定
def extension_allowlist
%w(jpg jpeg png)
end
end
今回のこの設定では、画像をアップロードした時にRailsの「app/public/uploads」ディレクトリに画像が追加されるようになります。
最後にpostモデルのimageカラムにImageUploaderを設定します。
このアップローダー指定は、先程のコマンド生成された「app/uploaders/image_uploader.rb」の中のクラス名を指定しましょう。
今回はImageUploaderを指定していきます。
app/models/post.rb
class Post < ApplicationRecord
mount_uploader :image, ImageUploader
end
これでRails側の設定が終わりました。
今回の実装により、React側で画像を投稿することが可能になりました。
次回のReact編で、本題となる画像プレビュー機能と画像投稿を実装していきたいと思います。