19
21

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 5 years have passed since last update.

【rails】投稿画像を非同期通信で表示する。

Last updated at Posted at 2017-05-25

画面遷移せずに、非同期通信によってビューに画像を表示したいときがあります。
基本的にはコメントと同じく以下の流れのように編集すればいいのですが、
ところどころコメントと異なり、少しクセがあります。

・画像を取得できるようにフォームを作る。hamlを編集
・画像を非同期通信で取得する。jsを編集
・ajax通信を成功させる。コントローラを編集
・画像を表示できるようにする。ビューを編集

【工程-1】画像を取得できるようにフォームを作る。hamlを編集

まず画像を投稿できるようにフォームを作ります。
file_field :imageを使います。

index.haml
 = form_for [@chatgroup, @comment] ,html: {class: 'form'} do |f|
    = f.submit "Send", class: 'chat-contents__type-message__button'
      .chat-contents__type-message__box
        %label
          = f.file_field :image

【工程-2】画像を非同期通信で取得する。jsを編集

以下の記述でformの内容を非同期通信します。
file_field :imageがあれば、画像のデータもこの中に含まれます。
イベントを発生させ、ajax通信を開始し、成功したらhtmlを変更し、
フォームの内容と入力欄をリセットするという記述です。

comment.js
  $('.form').on("submit", function(e) {
    e.preventDefault();
    var formdata = new FormData($(this).get(0));
    $.ajax({
      type: 'POST',
      url: window.location.href,
      data: formdata,
      dataType: 'json',
      contentType: false,
      processData: false,
      disabled: false
    })
    .done(function(data){
      buildHTML(data);
      var textField = $('.chat-contents__type-message__box__message')
      $(textField).val('')
      $('.chat-contents__type-message__button').removeAttr("disabled");
      alert('送信が成功しました')
    })
    .fail(function(error){
      alert('error')
    });
  });

【工程-3】ajax通信を成功させる。コントローラを編集

controllerにformat.jsonを記述します。

controller.rb
  def create
    @comment = @chatgroup.comments.new(comment_params)
    if @comment.save
      respond_to do |format|
        format.html { redirect_to chatgroup_comments_path }
        format.json
      end
    else
      flash.now[:alert] = "メッセージ送信失敗!"
      render :index
    end
  end

imageを渡せるようにjbuilderにも記述します。

create.json.jbuilder
json.image @comment.image

【工程-4】画像を表示できるようにする。ビューを編集

ページを読み込んだときに表示できるようにhamlに記述します。
mcommentテーブルのimageをとってくるだけなので、簡単ですね。

comment.haml
=image_tag(comment.image, size: 256)

次に非同期通信に対応するように、jsに記述します。

comment.js
img src = '${data.image.url}' width="256" height="256"

コントローラーにimageがparamsとして渡っているのと、
jbuilderにjson.image @comment.imageと記述があることを前提としています。

ここまでで画像が表示できるようにはなっていると思います。

【調整-1】画像がないときにも対応できるように調整

画像は表示できるようになりましたが、このままでは画像がないときにも画像が収まる枠が表示されてしまいます。
両方に対応できるように条件分岐をしましょう。

comment.haml
var html = `hoge`
      if (data.image.url == null){
        html = $(html).append(`</li>`)
      } else {
        html = $(html).append(`<div class = 'hoge'><img src = '${data.image.url}' width="256" height="256"}</div></li>`)
      }
    $('.chat-contents__body__comments').append(html)

src = '${data.image.url}'とありますが、これはデータ属性を持たせるための記述です。非同期通信で画像を追加する前のものと比較するためです。

【調整-2】gitに画像のアップロードが認識されないよう、.gitignoreに記述を加える。

画像を投稿するごとにpublic/uploads/comment/imageに画像がどんどんストックされていきます。このままでは、gitに変更したものと認識されてしまうので、変更対象として認識されないようになります。.gitnoreに記述を加えることで、認識されないようにします。
.gitignoreはアプリケーションのディレクトリ直下にあります。私は最初、.gitignoreがあるのを知らず、command + newで自分で作ろうとしていました。自分で作ろうとしても拡張子使えんよって言われるので、やめましょう。

なお、.gitignoreについては、このリンク先がすごく詳しいです↓

.gitignoreの末尾に/imageと/tmpを記入

.gitignore
Ignore all logfiles and tempfiles.
/log/*
!/log/.keep
/image
/tmp

以上になります。

19
21
2

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
19
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?