質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

0回答

969閲覧

React * Rails API + CarrierWaveを使用しての画像のアップロードをしたい

mymt658

総合スコア15

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2022/05/25 17:21

バックエンドをrails,フロントをReactで開発を行っています。
Rails API CarrierWave
React

実現したいこと

フロント側であるReactからアップロードした画像をバックエンド側で保存?api通信できるようにしたい。

Rails 側でGemのCarrierWaveを使用しています。

CarrierWaveの設定などは下記リンクを参考に行なっています。
https://note.com/matsushoooo12/n/n6398a6600d20

発生している問題・エラーメッセージ

PUT http://localhost:3001/api/v1/users/9
500 (Internal Server Error) とエラーが出てしまいます。

イメージ説明

users_controller

1class Api::V1::UsersController < ApplicationController 2 before_action :set_user, only: %i[show update] 3 4 def index 5 # 都道府県が同じで性別の異なるユーザーを取得(自分以外) 6 users = User.all.order("created_at DESC") 7 render json: { status: 200, users: users } 8 end 9 10 def show 11 render json: { status: 200, user: @user } 12 end 13 14 def update 15 @user.name = user_params[:name] 16 @user.profile = user_params[:profile] 17 @user.image = user_params[:image] if user_params[:image] != "" 18 19 if @user.save 20 render json: { status: 200, user: @user } 21 else 22 render json: { status: 500, message: "更新に失敗しました" } 23 end 24 end 25 26 private 27 28 def set_user 29 @user = User.find(params[:id]) 30 end 31 32 def user_params 33 params.permit(:name, :profile, :image) 34 end 35end 36

Routes.rb

1Rails.application.routes.draw do 2 namespace :api do 3 namespace :v1 do 4 resources :test, only: %i[index] 5 resources :englishlists 6 resources :my_lists, only: %i[create] 7 resources :users, only: %i[index show update] 8 9 mount_devise_token_auth_for 'User', at: 'auth', controllers: { 10 registrations: 'api/v1/auth/registrations' 11 } 12 13 namespace :auth do 14 resources :sessions, only: %i[index] 15 end 16 end 17 end 18end 19

api関係

1import applyCaseMiddleware from "axios-case-converter" 2import axios from "axios" 3 4 5const options = { 6 ignoreHeaders: true 7} 8 9const client = applyCaseMiddleware( 10 axios.create({ 11 baseURL:"http://localhost:3001/api/v1" 12}), options) 13 14export default client 15 16 17 18import client from "./client" 19 20import Cookies from "js-cookie" 21 22export const getUser = (id) => { 23 return client.get(`users/${id}`) 24} 25 26export const updateUser = (id , data) => { 27 return client.put(`users/${id}`, data) 28}
const Home = () => { const { isSignedIn, setIsSignedIn, currentUser, setCurrentUser } = useContext(AuthContext) const classes = useStyles() const histroy = useNavigate() const [editFormOpen, setEditFormOpen] = useState(false) const [name, setName] = useState(currentUser) const [prefecture, setPrefecture] = useState(currentUser?.prefecture || 0) const [profile, setProfile] = useState(currentUser?.profile) const [image, setImage] = useState("") const [preview, setPreview] = useState("") // アップロードした画像の情報を取得 const uploadImage = useCallback((e) => { const file = e.target.files[0] setImage(file) }, []) // 画像プレビュー const previewImage = useCallback((e) => { const file = e.target.files[0] setPreview(window.URL.createObjectURL(file)) }, []) const createFormData = () => { const formData = new FormData() formData.append("name", name || "") formData.append("profile", profile || "") formData.append("image", image) return formData } const handleSubmit = async (e) => { e.preventDefault() const data = { name: name, profile: profile, image: image } // const data = await createFormData() console.log(data) try { const res = await updateUser(currentUser?.id, data) console.log(res) if (res.status === 200) { setEditFormOpen(false) setCurrentUser(res.data.user) console.log("Update user successfully!") } else { console.log(res.data.message) } } catch (err) { console.log(err) console.log("Failed in updating user!") } } // サインアウト用の処理 const handleSignOut = async (e) => { try { const res = await signOut() if (res.data.success === true) { // Cookieから各情報を削除 Cookies.remove("_access_token") Cookies.remove("_client") Cookies.remove("_uid") setIsSignedIn(false) histroy.push("/signin") console.log("Succeeded in sign out") } else { console.log("Failed in sign out") } } catch (err) { console.log(err) } } return ( <> { isSignedIn && currentUser ? ( <> <Card className={classes.card}> <CardContent> <Grid container justify="flex-end"> <Grid item> <IconButton onClick={() => setEditFormOpen(true)} > <SettingsIcon color="action" fontSize="small" /> </IconButton> </Grid> </Grid> <Grid container justify="center"> <Grid item> <Avatar alt="avatar" src={currentUser?.image.url} className={classes.avatar} /> </Grid> </Grid> <Grid container justify="center"> <Grid item style={{ marginTop: "1.5rem"}}> <Typography variant="body1" component="p" gutterBottom> {currentUser?.name} </Typography> <Divider style={{ marginTop: "0.5rem"}}/> <Typography variant="body2" component="p" gutterBottom style={{ marginTop: "0.5rem", fontWeight: "bold" }} > 自己紹介 </Typography> { currentUser.profile ? ( <Typography variant="body2" component="p" color="textSecondary"> {currentUser.profile} </Typography> ): ( <Typography variant="body2" component="p" color="textSecondary"> よろしくお願いいたします。 </Typography> ) } <Button variant="outlined" onClick={handleSignOut} color="primary" fullWidth startIcon={<ExitToAppIcon />} style={{ marginTop: "1rem"}} > サインアウト </Button> </Grid> </Grid> </CardContent> </Card> <form noValidate autoComplete="off"> <Dialog open={editFormOpen} keepMounted onClose={() => setEditFormOpen(false)} > <DialogTitle style={{ textAlign: "center"}}> プロフィールの変更 </DialogTitle> <DialogContent> <TextField variant="outlined" required fullWidth label="名前" value={name} margin="dense" onChange={(e) => setName(e.target.value)} /> <TextField placeholder="1000文字以内で書いてください。" variant="outlined" multiline fullWidth label="自己紹介" rows="8" value={profile} margin="dense" onChange={(e) => { setProfile(e.target.value) }} /> <div className={classes.imageUploadBtn}> <input accept="image/*" className={classes.input} id="icon-button-file" type="file" onChange={(e) => { uploadImage(e) previewImage(e) }} /> <label htmlFor="icon-button-file"> <IconButton color="primary" aria-label="upload picture" component="span" > <PhotoCamera /> </IconButton> </label> </div> { preview ? ( <Box className={classes.box} > <IconButton color="inherit" onClick={() => setPreview("")} > <CancelIcon /> </IconButton> <img src={preview} alt="preview img" className={classes.preview} /> </Box> ) : null } </DialogContent> <DialogActions> <Button onClick={handleSubmit} color="primary" disabled={!name || !profile ? true : false} > 送信 </Button> </DialogActions> </Dialog> </form> </> ) : ( <></> ) } <Link to="/list">List</Link> </> ) } export default Home

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問