rails,vue.js初学者です。
前提・実現したいこと
railsのAPIサーバとVue.jsを使用して、FormDataを使用して画像ファイルや動画ファイルをaxiosでPOSTしたい。
発生している問題・エラーメッセージ
vue側でFormDataを使用しそれぞれ、image,video,text,user_idをappendしてaxiosでPOSTした際にrailsサーバで以下のようなエラーが発生する。
Started POST "/api/posts" for ::1 at 2020-03-15 17:49:34 +0900 Processing by Api::PostsController#create as JSON Parameters: {"image"=>#<ActionDispatch::Http::UploadedFile:0x00007f88d80bab68 @tempfile=#<Tempfile:/var/folders/sd/cjky7p2d1_vg464prg9nx89h0000gn/T/RackMultipart20200315-44329-dppqtn.jpeg>, @original_filename="Award、優勝・受賞の無料アイコン素材 1.jpeg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"image\"; filename=\"Award\xE3\x80\x81\xE5\x84\xAA\xE5\x8B\x9D\xE3\x83\xBB\xE5\x8F\x97\xE8\xB3\x9E\xE3\x81\xAE\xE7\x84\xA1\xE6\x96\x99\xE3\x82\xA2\xE3\x82\xA4\xE3\x82\xB3\xE3\x83\xB3\xE7\xB4\xA0\xE6\x9D\x90 1.jpeg\"\r\nContent-Type: image/jpeg\r\n">, "video"=>#<ActionDispatch::Http::UploadedFile:0x00007f88d80ba988 @tempfile=#<Tempfile:/var/folders/sd/cjky7p2d1_vg464prg9nx89h0000gn/T/RackMultipart20200315-44329-jv9gni.mp4>, @original_filename="neco03_720.mp4", @content_type="video/mp4", @headers="Content-Disposition: form-data; name=\"video\"; filename=\"neco03_720.mp4\"\r\nContent-Type: video/mp4\r\n">, "user_id"=>"1", "text"=>"ttt"} Completed 400 Bad Request in 0ms (ActiveRecord: 0.0ms | Allocations: 124) ActionController::ParameterMissing (param is missing or the value is empty: post): app/controllers/api/posts_controller.rb:64:in `post_params' app/controllers/api/posts_controller.rb:20:in `create'
該当のソースコード
ruby
1def create 2 binding.pry 3 @post = Post.new(post_params) 4 @post.pictures.build(image: params[:post][:image], video: params[:post][:video], user_id: params[:post][:user_id]) 5 @post.pictures.each do |picture| 6 picture.post_id = @post.id 7 end 8 if @post.text.blank? 9 response_bad_request 10 elsif @post.save 11 response_success("投稿") 12 else 13 response_internal_server_error 14 end 15 end 16 . 17 . 18 . 19private 20def post_params 21 params.require(:post).permit(:text, :user_id) 22 end
vue
1<template> 2 <div class="user-new-wrapper"> 3 <div class="container"> 4 <div class="row"> 5 <div class="col-md-offset-4 col-md-4 form_box"> 6 <h1>投稿する</h1> 7 <p v-show="errored">投稿に失敗しました。</p> 8 <form @submit.prevent="createPost"> 9 <div class="form-group"> 10 <label for="image">画像</label> 11 <input type="file" name="image" id="image" accept=".jpg, .jpeg, .gif, .png" @change="selectedImage"> 12 </div> 13 <div class="form-group"> 14 <label for="video">動画</label> 15 <input type="file" name="video" id="video" accept=".mp4" @change="selectedVideo"> 16 </div> 17 <div class="form-group"> 18 <label for="text">テキスト</label> 19 <textarea rows="6" cols="18" id="text" name="text" class="form-control form-text" v-model='post.text'></textarea> 20 </div> 21 <input type="submit" value="投稿" class="btn-block btn-white" v-if="post.logged_in > 0"> 22 </form> 23 </div> 24 </div> 25 </div> 26</div> 27</template> 28 29<script> 30import axios from 'axios' 31 32const hostName = 'localhost:3000' 33const path = '/api/posts' 34 35export default { 36 name: 'postNew', 37 data: function () { 38 return { 39 post: { 40 uploadImage: null, 41 uploadVideo: null, 42 text: '', 43 logged_in: 0 44 }, 45 errored: false, 46 res: { 47 message: '' 48 } 49 } 50 }, 51 created: function () { 52 this.post.logged_in = this.$localStorage.get('loginUser') 53 }, 54 methods: { 55 selectedImage (e) { 56 e.preventDefault() 57 let files = e.target.files 58 this.post.uploadImage = files[0] 59 console.log(this.post.uploadImage) 60 }, 61 selectedVideo (e) { 62 e.preventDefault() 63 let files = e.target.files 64 this.post.uploadVideo = files[0] 65 console.log(this.post.uploadVideo) 66 }, 67 createPost () { 68 var formdata = new FormData() 69 formdata.append('image', this.post.uploadImage) 70 formdata.append('video', this.post.uploadVideo) 71 formdata.append('user_id', this.post.logged_in) 72 formdata.append('text', this.post.text) 73var config = { 74 headders: { 75 'content-type': 'multipart/form-data' 76 } 77 } 78 axios.post(`http://${hostName}${path}`, 79 formdata, {config}).then((result) => { 80 this.$router.push('/') 81 this.res = result.data 82 this.$emit('flash', (this.res.message)) 83 }).catch(error => { 84 console.log(error) 85 this.errored = true 86 }) 87 } 88 } 89} 90</script> 91
試したこと
binding.pryでparams[:post]の値を調べて見るとnilと表示された。原因はこれで間違いないが、なぜ値が入らないのか分からない。
@postのストロングパラメータを消してPOSTしてみたが、
NoMethodError (undefined method `[]' for nil:NilClass):
というエラーが表示された。これも、params[:post]に値が入っていないから起こるエラーらしい。
3日ほどここに悩まされています。
どうか回答よろしくお願いします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/03/17 08:22