チワワかわいいブログ

RUNTEQでrails勉強する日々の記録

2020/12/31 carrier_wave

掲示板に画像投稿機能をつける carrier_waveとmini_magickという2つのgemを使う
参考 techtechmedia.com carrier_wave→ファイルアップロード用のgem
mini_magick→ファイル編集用のgem。利用にあたりImageMagickというソフトのインストールが必要。

実装する
$ brew install imagemagick #ImageMagickをインストール

/gemfile
gem 'carrierwave'
gem 'mini_magick'

$ bundle install

ここまで実行すると、アップロード用のクラスを作成するコマンドを実行できるようになる。
画像のフォーマットやサイズなどの設定をこのクラスに記述することになる。
モデルが異なる場合でも記述した設定を使いまわしたりできるので、色々なモデルでアップローダーを使う場合に柔軟に対応できる。

$ rails generate uploader image

次にboardモデルに新しいカラムを作成。

class AddBoardImageToBoards < ActiveRecord::Migration[5.2]
  def change
    add_column :boards, :board_image, :string
  end
end

このカラムに対して画像をアップロードして、それをアップローダーが処理することになるため、
カラムとアップローダーの関連付けを行う。

class Board < ApplicationRecord
  mount_uploader :board_image, ImageUploader
end

アップローダーにminimagick経由で加工するため追記。

#image_uploader.rb

class ImageUploader < CarrierWave::Uploader::Base 
  include CarrierWave::MiniMagick
  process resize_to_fit: [300, 200]
end

画像投稿のviewを編集して、画像用のフォームを追加 。

<%= f.label :board_image, t('.thumbnail') %>
<%= f.file_field :board_image, class: 'form-control' %>

画像の拡張子を制限

#image_uploader.rb

def extension_whitelist
    %w(jpg jpeg gif png)
end

javascriptを使って洗濯した画像のサムネイルを表示

<div>
  <% if @board.board_image.present? %>
  <%= image_tag @board.board_image, id: :img_prev %>
 <% else %>
  <%= image_tag '70017892-c40bbc00-15c7-11ea-8022-9cb7e5d22aa1.png', id: :img_prev %>
 <% end %>
  <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]);
          }
      }
      $("#board_board_image").change(function(){
          readURL(this);
      });
    });
  </script>

フォームで保存した画像は、image_tag 〇〇.urlで表示できる

<%= image_tag board.board_image.url  %>
ポイントを見ながらリファクタリング
  • avascriptの記載はapplication.jsに記載せず、別途専用ファイルを定義する

  • 画像アップロードがない場合のデフォルト画像を、image_uploader.rbに設定しておく
    →indexやshowファイルにif文を描かなくても、勝手にデフォルト画像が表示されてくれる

  • ローカル環境でアップロードした画像ファイルはアップロードしないようgitignoreを追記していること

    • すでにファイルをコミットしてからgitignoreを追記してもファイルが管理対象に含まれているため、コミット後はgit rm --cached ファイル名コマンドでgitの管理対象外に設定する
    • 不要なファイルをpushしてしまった場合は、git rm ファイル名コマンドでリモートリポジトリから削除する
  • board_image_cacheの補足説明
    • アップロードに失敗した際もファイルが消えないようにするために必要 →他のフォームの不備で保存できなかった場合でも保持してくれる

参考

Rails:CarrierWaveで画像のプレビュー機能を実装 | Boys Be Engineer 非エンジニアよ、エンジニアになれ

https://workabroad.jp/tech/1118