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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Ruby on Rails

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

Amazon S3

Amazon S3 (Simple Storage Service)とはアマゾン・ウェブ・サービスが提供するオンラインストレージサービスです。

Q&A

解決済

1回答

1101閲覧

railsでAPIを使ったアップローダーのpostエラー

ajisainoalibi

総合スコア7

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Ruby on Rails

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

Amazon S3

Amazon S3 (Simple Storage Service)とはアマゾン・ウェブ・サービスが提供するオンラインストレージサービスです。

0グッド

0クリップ

投稿2020/05/21 16:25

編集2020/05/22 09:29

###やりたいこと
下記の記事を参考にしたVue + Rails + CarrierwaveでS3へのダイレクトアップロード
Vue + Rails + CarrierwaveでS3へのダイレクトアップロードをする

何が起きたか

記事の通りに行ったところ下記のようなエラー文が返ってきてしまいました。

TypeError: Cannot read property 'post' of undefined

デバッグの方法などが分からず、エラー箇所が特定できません。。。

関連していると思われるコード

※基本的に記事内のコードを丸々コピーしていますが念のため記載しております。

app/script/test.vue

vue

1<template> 2 <input 3 class="custom-file-input" 4 type="file" 5 name="products[image]" 6 ref="productImage" 7 > 8 <div class="form-group"> 9 <input 10 type="submit" 11 name="commit" 12 value="アップロード" 13 class="btn btn-success submit" 14 data-disable-with="アップロード" 15 @click="postProduct" 16 > 17 </div> 18</template> 19 20<script> 21import axios from "axios"; 22 23axios.defaults.headers.common = { 24 'X-Requested-With': 'XMLHttpRequest', 25 'X-CSRF-TOKEN' : document.querySelector('meta[name="csrf-token"]').getAttribute('content') 26}; 27 28export default { 29 data: function() { 30 return { 31 value: '', 32 presignedUrl: '', 33 uploadFile: {}, 34 productId: '' 35 }; 36 }, 37 methods: { 38 async postProduct (e) { 39 try { 40 this.uploadFile = this.$refs.productImage.files[0] 41 const postingUrl = `/api/v1/products` 42 const payload = { 43 product: { 44 image: this.uploadFile.name 45 } 46 } 47 const res = await this.$axios.post(postingUrl, payload) 48 this.presignedUrl = res.data.image_url 49 this.productId = res.data.id 50 this.fileUpload() 51 } catch(e) { 52 console.error(e) 53 } 54 }, 55 56 async fileUpload () { 57 try { 58 const config = { 59 headers: { 60 'content-type': 'multipart/form-data' 61 } 62 } 63 // formDataは使わずファイルをそのままアップロードする 64 await this.$axios.put(this.presignedUrl, this.uploadFile, config) 65 } catch(e) { 66 console.error(e) 67 } 68 } 69 70 } 71}; 72</script>

config/initializers/aws.rb
※バケット名やKEYは自分の発行したものを入れております

Ruby

1unless Rails.env.test? || Rails.env.development? 2 credentials = Aws::Credentials.new( 3 ENV["S3_ACCESS_KEY_ID"], 4 ENV["S3_SECRET_ACCESS_KEY"] 5 ) 6 7 s3_resource = Aws::S3::Resource.new(region: 'bucketのリージョン名', credentials: credentials) 8 S3_BUCKET = s3_resource.bucket('S3のバケット名') 9end

app/uploaders/application_uploader.rb

Ruby

1class ApplicationUploader < CarrierWave::Uploader::Base 2 # Include RMagick or MiniMagick support: 3 # include CarrierWave::RMagick 4 # include CarrierWave::MiniMagick 5 6 # Choose what kind of storage to use for this uploader: 7 storage :file 8 # storage :fog 9 10 # Override the directory where uploaded files will be stored. 11 # This is a sensible default for uploaders that are meant to be mounted: 12 def store_dir 13 "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" 14 end 15 16 # Provide a default URL as a default if there hasn't been a file uploaded: 17 # def default_url(*args) 18 # # For Rails 3.1+ asset pipeline compatibility: 19 # # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_')) 20 # 21 # "/images/fallback/" + [version_name, "default.png"].compact.join('_') 22 # end 23 24 # Process files as they are uploaded: 25 # process scale: [200, 300] 26 # 27 # def scale(width, height) 28 # # do something 29 # end 30 31 def presigned_url(file_name = nil) 32 file_name ||= self.model.attributes[mounted_as.to_s] 33 object = S3_BUCKET.object([store_dir, file_name].join('/')) 34 # 署名付きリンクは10分で失効(デフォルトでは15分) 35 object.presigned_url(:put, expires_in: 10.minutes.to_i, acl: 'private') 36 end 37 38 # Create different versions of your uploaded files: 39 # version :thumb do 40 # process resize_to_fit: [50, 50] 41 # end 42 43 # Add a white list of extensions which are allowed to be uploaded. 44 # For images you might use something like this: 45 def extension_whitelist 46 %w(jpg jpeg gif png) 47 end 48 49 # Override the filename of the uploaded files: 50 # Avoid using model.id or version_name here, see uploader/store.rb for details. 51 # def filename 52 # "something.jpg" if original_filename 53 # end 54end

app/controllers/api/v1/products_controller.rb

Ruby

1class Api::V1::ProductsController < ApplicationController 2 def create 3 @products = Image.new(products_params) 4 # 先に@productsのオブジェクトを作成し、後からファイルカラムを更新する 5 if @products.save! 6 @products.update_column('image', products_params[:image]) 7 render json: { 8 id: @products.id, 9 image_url: @products.image.presigned_url 10 } 11 else 12 render json: @products.errors, status: :unprocessable_entity 13 end 14 end 15end

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

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

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

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

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

guest

回答1

0

自己解決

axiosがすでに使えるのに変数的な扱いをしてしまっているからこそ出ていたエラーでした。

const res = await this.$axios.post(postingUrl, payload) await this.$axios.put(this.presignedUrl, this.uploadFile, config)

この二つのコードを

const res = await axios.post(postingUrl, payload) await axios.put(this.presignedUrl, this.uploadFile, config)

このように変える必要がありました。

投稿2020/06/07 08:46

ajisainoalibi

総合スコア7

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問