2
1

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.

「Rails6」Active Storageを使った画像のプレビュー機能

Last updated at Posted at 2022-05-30

前提条件

  • ruby 2.6.8
  • Rails 6.1.5
  • ActiveStorageをインストール済
  • slimを使用

概要

 画像を投稿する際,画像を選ぶと、画像プレビュー機能を実装してどういった画像が投稿されるか確認できるようにします。 イメージ画像を以下に添付します。

image.png

実装

画像のプレビュー機能は、ActiveStorageのメソッドではなく、Jqueryで実装します。 そのためには、Jqueryを設置する必要があります。Rails6ですので、下記のコマンドが便利ですね。

docker-compose run web yarn add jquery-ujs

では下記がコードになります。※CSSのコードは除きます。

posts/edit.html.slim
.form-upload.make-center-column
  .uploadimage
    - if @user.profile_picture.attached?
        = image_tag url_for(@user.profile_picture), class: "upload-image", id: 'preview'
    - else
        = image_tag "nopic.jpg", class: "upload-image", id: 'preview'
  = form_with model: [:info, @user], method: :patch do |user|
    = user.file_field :profile_picture, class: "photo_upload", id: "user_img", 
      onchange: "previewImage(this)",accept: 'image/jpg,image/jpeg,image/png,image/gif'

    .form-control
      = user.label "お名前"
      = user.text_field :name, value: current_user.name
    .form-control
      = user.label "自己紹介"
      = user.text_area :introduce, value: current_user.introduce

    = user.submit '編集', class: 'form-button'

  = link_to '戻る', info_user_path(current_user), class: 'form-button'

javascript:

 function previewImage(obj)
  {
    var fileReader = new FileReader();
    fileReader.onload = function() {
    var element = document.getElementById('preview');
    element.src = fileReader.result;
        }
        fileReader.readAsDataURL(obj.files[0]);
    };

3行目の- if @user.profile_picture.attached?は既に画像を設定しているかを確認して、画像がありましたら、現在の画像を表示します。
なかったら、nopic.jpgを表示します。

そして今回肝になるコードが8行目の下記です。

= user.file_field :profile_picture, class: "photo_upload", id: "user_img", 
  onchange: "previewImage(this)",accept: 'image/jpg,image/jpeg,image/png,image/gif'

onchange: "previewImage(this)"で、ファイルの選択を検知するとJavascriptのpreviewImage(this)が実行されます。
ちなみにaccept:'image/jpg,image/jpeg,image/png,image/gifで、アップロードする形式を限定することができます。

Javascriptのコードを説明しますと、選択されたイメージのURLをidがpreviewの要素のsrcに格納します。

javascript:

 function previewImage(obj)
  {
    var fileReader = new FileReader();
    fileReader.onload = function() {
    var element = document.getElementById('preview');
    element.src = fileReader.result;
        }
        fileReader.readAsDataURL(obj.files[0]);
    };

つまり下記のコードは既に画像を設定されているときは、@user.profile_pictureを表しますが、新たにファイルが選択されると、imageタグのsrcが選択されたファイルのURLに変わって、選択されたファイルを表すことになります。

= image_tag url_for(@user.profile_picture), class: "upload-image", id: 'preview'

終わりに

書いてみると、とても簡単なコードですが、具現化まで結構時間がかかりました。

Active Storageにまだ慣れてないこともありますが、Active Storageにpreviewメソッドがあると勝手に思い込んだのが主な原因ですね、、
Active storage image previewばかり検索していました。
何かを調べる時は思い込まないことが大事だとこのpreview機能から習うことができましたね。

以上です。imageのpreview機能を追加したい方々にちょっとでもご参考になったら嬉しいです。
ご指摘等ございましたら、教えてください。

2
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?