LoginSignup
11
9

More than 3 years have passed since last update.

【Rails】Railsに保存した画像ファイルをVue.js側で表示するサンプルコード(Base64、Active Storage使用)

Last updated at Posted at 2020-02-09

はじめに

Rails APIモード→Vue.jsでの画像データのやりとりをする方法を残します。(Base64、Active Storage使用)

今回の対象

:x: Vue.js→Rails(こちらの記事をご参照下さい。引用失礼します!)
:o: Rails→Vue.js ←ココ

環境

OS: macOS Catalina 10.15.3
Ruby: 2.6.5
Rails: 6.0.2.1
Vue: 2.6.10
axios: 0.19.0

前提:実施済とみなすこと

引用記事の例を使用します。

  • rails new
  • Active Storageのインストール
  • Postモデルの作成
  • Vue.jsのインストールと利用するための準備
  • eyecatchとして画像ファイルがPostモデルのインスタンスに添付されている
  • (今ココ)

1.【Rails】画像ファイルをBase64形式でエンコードするメソッドを定義する

posts_controller.rb
  # 各モデルのレコードに添付された画像ファイルをBase64でエンコードする
  def encode_base64(image_file)
    image = Base64.encode64(image_file.download) # 画像ファイルをActive Storageでダウンロードし、エンコードする
    blob = ActiveStorage::Blob.find(image_file[:id]) # Blobを作成
    "data:#{blob[:content_type]};base64,#{image}" # Vue側でそのまま画像として読み込み出来るBase64文字列にして返す
  end

2.【Rails】Active Storageでアタッチした画像ファイルを読み込み

posts#showで投稿データを返すとします。

posts_controller.rb
  def show
    post = Post.find(params[:id]).as_json #JSON形式にしておく

    eyecatch = post.eyecatch #eyecatchは添付した画像ファイル

    if eyecatch.present?
      post['image'] = encode_base64(eyecatch) # 画像ファイルを1.で定義したメソッドでBase64エンコードし、renderするデータに追加する
    end

    render json: post
  end

3.【Rails】ルーティングを設定

Rails.application.routes.draw do
# 略
  get 'posts', to: 'posts#show'
# 略
end

4.【Vue.js】画像を取得し、表示するコンポーネントを作成

show.vue
<template>
  <div>
    <p>投稿表示フォーム</p>

      <!-- preventでsetPost()メソッドがページ遷移なく発火する -->
    <form v-on:submit.prevent="setPost()">
      <p>
        <label>Title</label>
        <input name="post.title" type="text" v-model="post.title"><br />
      </p>
      <p>
        <label>Body</label>
        <input name="post.body" type="text" v-model="post.body"><br />
      </p>

      <!-- post.idを指定して... -->
      <p>
        <label>IDを指定</label>
        <input name="post.id" type="text" v-model="post.id">
      </p>

      <!-- ここを押してデータ取得 -->
      <input type="submit" value="ここを押して投稿データ取得" >

      <!-- Base64形式であればimgタグでそのまま読み込みが可能 -->
      <img :src="post.image" alt="post.image">
    </form>
  </div>
</template>

<script>
import axios from 'axios'

export default {
  name: 'sample',
  data() {
    return {
      post: {},
    }
  },
  methods: {
    setPost() {
      axios.get('/posts', {params: {id: this.post.id}}) //入力したidに応じてpostが返ってくる
      .then(response => {
        this.post = response.data 
      })
      .catch( error => {
        console.error(error)
      })
    }

  }
}
</script>

※実際は自分でidを指定することはないと思いますので、状況に応じて変更して頂ければと思います。

以上です!

おわりに

最後まで読んで頂きありがとうございました:bow_tone1:

どなたかの参考になれば幸いです:relaxed:

参考にさせて頂いたサイト(いつもありがとうございます)

11
9
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
11
9