見出し画像

【Rails5】初心者へ勧める!実用的な画像投稿フォームの優しい作り方

目次
1.はじめに
2.画像保存用のカラムと画像投稿フォームの作成
 2-1.画像保存用のカラムの作成
 2-2.画像のアップロードを簡単にする”carrierwave”用意
  2-2-1.carrierwaveのインストール
  2-2-2.画像が保存されるmount_uploaderを用意
 2-3.フォームに画像アップロードフォームを追加する
3.画像の削除
4.アップロードした画像を編集画面上でプレビューする
 4-1.今なんの画像が保存されていたが確認できない
 4-2.file_fieldに入れた画像のプレビューを編集画面で確認
  4-2-1.Javascriptを使うための下準備
  4-2-2.jQueryを使用してアップロードした画像のプレビューを表示させる


1.はじめに

Railsを始めたばかりの方は、carrierwaveというgemを使用してよく画像投稿フォームを作ります。

しかし作っただけで、実用性を考えると以下のような点が足りておらずユーザーとしては不便さを感じてしまうような点があります。

・投稿した画像の削除ができない
・アップロードした画像を入力フォーム上で確認できない

今回は、画像投稿フォームの作り方に加えて上記2点を追加した、実用的な画像投稿フォームの作り方をご紹介します。

また、本記事は機能の実装をメインにご紹介しているために
CSSは今回1つも書いていないです。
私ごとですがご要望があると、更新作業のモチベーション高くなりますのでコメントいただけると幸いです。m(_ _)m

2.画像保存用のカラムと画像投稿フォームの作成

まずは基本的な画像投稿が出来るように作っていきます。

2-1.画像保存用のカラムの作成

現在は、本の名前と値段を保存するカラムがあるとします。

irb(main):001:0> Book.column_names
=> ["id", "name", "price", "created_at", "updated_at"]

ここに本の画像を保存するためのimgというカラムを追加します。

コマンド:rails g migration AddImgToBooks img:string

でBooksモデルにimgというstring型のカラムが追加されます。
上記コマンドを実行したら、続けて

rals db:migrate

を実行します。

これで、画像を保存するカラムの追加は完了です。

2-2.画像のアップロードを簡単にする”carrierwave”用意

2-2-1.carrierwaveのインストール
Gemfileに

gem 'carrierwave'

を追加しターミナル上で

bundle install

を実行しcarrierwaveをインストールします。

2-2-2.画像が保存されるmount_uploaderを用意
残りは実際に画像をファイルに保存するためのアップローダーファイルを用意します。

ターミナル上で

コマンド:ralis g uploader img

を実行します。すると下記のようにuploadersディレクトリとimg_uploader.rbファイルが生成されます。・・・・・・

コマンドの実行をし、img_uploader.rbが作成されたらapp/model/book.rbに下記のように記述します。

class Book < ApplicationRecord
 mount_uploader :img, ImgUploader
end

これで下準備は整いました。

※一度サーバーを閉じないとmount_uploaderの記述をエラーと認識されることがあります。

2-3.フォームに画像アップロードフォームを追加する
railsではfile_fieldでファイルのアップロードフォームが作成できます。

   <%= form.label :img %>
   <%= form.file_field :img, id: :book_img %>

現状↓

フォームの追加が完了したら、

booksコントローラーでpermitするカラムの追加も行いましょう。

 def book_params
     params.require(:book).permit(:name, :price,:img)
 end

として":img"を追加してあげます。

これでフォームにアップロードした画像をDBに保存することができるようになりました。

[
["name", "CarrierWave"],
["price", 3000],
["created_at", "2018-02-27 03:14:01.488252"],
["updated_at", "2018-02-27 03:14:01.488252"],
["img", "pronear.png"]
]

で保存が正しくされているのがわかるかと思います。

あとは画像の表示は以下のコードを追加することで出来るようになります。

<%= image_tag @book.img.url %>

3.画像の削除

実はこのままだと、選択された画像の削除というのができません。

編集でファイルアップロードフォームを「選択されていません」にして保存をしても、実はデータベースから画像消えるわけではないため画像の削除ができなくなってしまうのです。

そこでこれを解決するものとして画像用のカラム名の頭に”remove_”をつけて削除ようの属性と認識させるやり方があります。

具体的に実例をみていきましょう。

現状

<%= form.label :img %>
<%= form.file_field :img, id: :book_img %>

に対して

<p><%= form.check_box :remove_img %>画像を削除する</p>

を追加してあげます。remove_カラム名です。

するとフォーム上では以下のようなチェックボックスが生成されます。

あとは属性を追加したので、app/controllers/books_controller.rbのpermit
にも追加した属性を描いてあげます。

def book_params
   params.require(:book).permit(:name, :price,:img,:img_cache,:remove_img)
end

これでデータベースに保存されて消すことのできなかった画像を削除することが出来るようになります。

4.アップロードした画像を編集画面上でプレビューする

データベースにある画像の削除は出来るようになりましたが、まだ利便性が非常に悪いです。例えば

1.今なんの画像が保存されていたが確認できない
2.アップロードするfile_fieldに入れた画像のプレビューを編集画面で確認できない

まずは "1.今なんの画像が保存されていたが確認できない"
について解決していきます。

4-1.今なんの画像が保存されていたが確認できない
編集画面でも画像の確認ができるようにするためには、

編集画面でもshow.html.erbでやったように画像があれば画像をimage_tagで画像を表示させれば大丈夫です。

実際のソースコードは以下です。

<%= image_tag @book.img.url if @book.img? %>

これで画像が保存されている場合には、画像を編集画面で見ることができるようになりした。

4-2.file_fieldに入れた画像のプレビューを編集画面で確認
現在の仕様では、file_fieldに新しく画像を入れてもデータベースに入っている画像が表示され、新しくアップした画像は保存するまで見ることができません。

そこでここではアップロードした画像をプレビュー出来るようにしていきましょう。

実はメインで使うのはJavascriptになるのですが、まずはJavascriptを正しく動かせるように編集画面の下準備をしましょう。

4-2-1.Javascriptを使うための下準備
まずは先ほど編集画面で画像を表示させるようにしたコードにIDをつけていきます。今回は、Javascriptのコードをコピペで動くようにしたいためid名も”img_prev”にしましょう。

<%= image_tag @book.img.url, id: :img_prev if @book.img? %>

上記でIDの設定は完了しました。

続いてjQueryを使うためにapp/views/layout/application.html.erbにてjQueryのCDNを読み込みましょう。

<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>

ここでRailsでjQueryを使う際のすごく大事な点があります!!

先のjQueryのCDNのコードは必ず

<%= javascript_include_tag 'application',ata-turbolinks-track': 'reload' %>
のコードより上に描いてください。

そうでないと、jQueryは動きません。ここは初心者がよくつまづいてしまうポイントなので気をつけましょう。

例えば下記のように描いてみましょう。

app/views/layout/application.html.erb

<!DOCTYPE html>
<html>
  <head>
  <title>BookAdmin</title>
  <%= csrf_meta_tags %>
  <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
  <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
  <body>
    <%= yield %>
  </body>
</html>

これでjQueyのコードを使う下準備は完了です。

4-2-2.jQueryを使用してアップロードした画像のプレビューを表示させる

上記までを正しく行うことができればプレビューの表示はあとは以下のコードを適切な場所へ貼り付けるだけで完了します。

貼り付ける場所は、

<%= form.file_field :img, id: :book_img %>

以下に貼り付けるようにしましょう。

<script type="text/javascript">
$(function() {
 function readURL(input) {
   if (input.files && input.files[0]) {
     var reader = new FileReader();
     reader.onload = function (e) {
       $('#img_prev').attr('src', e.target.result);
     }
     reader.readAsDataURL(input.files[0]);
   }
 }
 $("#book_img").change(function(){
   readURL(this);
 });
});
</script>

これで編集画面でアップロードした画像のプレビューが出来るようになりました。


この記事が気に入ったらサポートをしてみませんか?