freks blog

about

React.js + Rails API modeでファイルをアップロードする

created: 2024-06-28
updated: 2024-08-22
おすすめ記事: 出会ってよかったプログラマー本

Userにavatar画像をアップロードする例を考えます
RailsはActive Storageを使います

Ruby 3.2.2
Rails 7.0.6 React.js 18.2.0 の環境で確認しています

ポイント

React.jsでは、FormData'Content-Type': 'multipart/form-data' で送信
Railsでは特別必要なことはしなくていい

実装例

Active Storage の概要 - Railsガイド を見てActive Storageを設定
Railsで、Userデータを作成するAPIを用意

route.rbに増やしたりして、コントローラーを作成
コントローラーのコードは普通のUser作成APIと同じですが、Strong Parametersにavatarを追加して緩和しておきました
User.column_names は、手抜きなので必要なものに絞ったほうがいいです

class UsersController < ApplicationController

  def create
    attendee_profile = User.new(user_params)
    attendee_profile.save!

    render json: attendee_profile, status: :created
  end

private

  def user_params
    params.require(:attendee_profile).permit(User.column_names, :avatar)
  end
end

React.jsでアップロード

const formValues: { avatar: File } = {
  avatar: avatarFile,
}

const body = new FormData();
body.append('users[avatar]', formValues.avatar);

await fetch('sample.com/users', {
    method: 'POST',
    headers: {
      // 'Content-Type': 'multipart/form-data',
      Authorization: 'Bearer ' + token,
    },
    body: body,
  });

といった感じでアップロードできます
fetchの場合は、'Content-Type': 'multipart/form-data' を指定するとおかしくなるので注意です

参考: fetch で multipart/form-data を送る時は Content-Type を指定してはいけない

axiosなら指定してうまくいきました

まとめ

いつも思い出すのが大変なので、メモしておきました


Amazonのアソシエイトとして、blog.freks.jp は適格販売により収入を得ています。
This site is managed by freks