###やりたいこと
下記の記事を参考にした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
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。