2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Nuxt.js x Ruby on Rails で画像ファイルを含む内容を保存させるときにやること

Last updated at Posted at 2022-05-16

はじめに

フロントエンドにNuxt.js、バックエンドにRails APIモードでの画像ファイルを含む内容を保存させるときにやることの記事です。
Nuxt.js、Railsはそれぞれ構築済みであることとします。

必要なもの

gem carrierwave

実装方法

Rails

1. Gemfileにcarrierwaveを追記しターミナルでbundle installします。

Gemfile
...途中省略
gem 'carrierwave', '~> 2.0'
ターミナル
bundle install

2. アップローダークラスの生成
ターミナルで下記コマンドを実行してアップローダークラスを生成します。

ターミナル
bundle exec rails g uploader アップローダー名(大文字始まり)

実行すると、/app/uploaders/アップローダー名_uploader.rbが生成されます。
Imageの場合は下記のようになります。

ターミナル
bundle exec rails g uploader Image

3.アップロードする画像のカラムをテーブルに追加します。
アップロードする画像情報を保存するカラムをテーブルに追加するマイグレーションファイルを作成します。
ターミナルで下記コマンドを実行します。

ターミナル
bundle exec rails g migration add_カラム名_to_テーブル カラム名:string 

マイグレーションファイルが作成されたら、ターミナルでマイグレーションを実行します。

ターミナル
bundle exec rails db:migrate

追加したカラムをコントローラのプライベートメソッドに追記します。

/app/controllers/v1/***_controllers.rb
module V1
  class ***Controller < ApplicationController
    ...途中省略
    def create
      *** = ***.create!(***_params)
      if ***.save
        render json: ***
      else
        render json: ***.errors
      end
    end

      private
    def ***_params
      params.require(:***).permit(:カラム名, :カラム名, :追加したカラム名)
    end
  end
end

4.アップローダークラスとカラムを紐付けます。

/app/models/***.rb
class モデル名 < ApplicationRecord
  mount_uploader :追加したカラム名, アップローダークラス
end

5..gitignoreに/public/uploadsを追記します。
保存に成功した画像ファイルは/public/uploadsに置かれるので、Git管理下から除外するため.gitignoreに追記します。

Nuxt.js

フロントエンドは親コンポーネントと子コンポーネントに分けます。

/pages/index.vue
<template>
  <AddImage @submit="addImage" />
</template>

<script>
import AddImage from '~/components/AddImage'
import axios from '~/plugins/axios'
export default {
  compoponents: {
    AddImage,
  },
  methods: {
    async addImage(formData, config) {
      await axios.post('バックエンドエンドポイント', formData, config)
        .then(() => {})
        .catch(() => {})
    }
  }
}
</script>
/components/AddImage.vue
<template>
  <v-form>
    <v-container>
      <v-row>
        <v-col
          cols="12"
          md="4"
        >
          <div>
            <v-file-input
              label="image"
              accept="image/*"
              v-model="addImage"
              prepend-icon="mdi-camera"
            />
          </div>
        </v-col>
        <v-col
          cols="12"
          md="4"
        >
          <v-btn
            @click="handleSubmit"
          >
            作成
          </v-btn>
        </v-col>
      </v-row>
    </v-container>
  </v-form>
</template>

<script>
export default {
  data () {
    return {
      addImage: []
    }
  },
  methods: {
    handleSubmit() {
      const formData = new FormData()
      formData.append('key', this.addImage)
      const config = {
        headders: {
          'content-type': 'multipart/form-data'
        }
      }
      this.$emit('submit', formData, config)
    }
  }
}
</script>

子コンポーネントの「作成」ボタンをクリックするとhundleSubmitが動き、emitを使用して子コンポーネントから親コンポーネントへデータを渡しています。

最後に

参考させていただいた記事をまとめます。
【Rails】 CarrierWaveチュートリアル
Vuetifyのv-file-inputで画像を送信する方法

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?