以前はgemなしで実装したので今度はCarrierWaveを使ってみる.
あとはせっかくなので画像のリサイズなんかも試す.
インストール
CarrierWaveで画像のリサイズなんかをやるためにはRMagickやMiniMagickが必要になります.
で, これらはImageMagickのラッパーなのでやっぱりImageMagickが必要になります.
Ubuntu(WSL)の場合.
$ sudo apt install imagemagick $ sudo apt install libmagick++-dev
サンプルプロジェクトを作成
$ rails new carrier_wave_sample
Gemfileを編集
今回はCarrierWave推奨のmini_magickを使います.
gem 'carrierwave' gem 'mini_magick'
bundleでインストール.
$ bundle install
とりあえず足場を作る
前回同様, scaffoldで.
とりあえず掲示板っぽいものを作成.
メッセージ毎に画像を1つ登録できるようにする.
$ rails g scaffold message message:string image_path:string $ rails db:migrate
uploaderを作る
uploaderはcarrierwaveで画像をアップロードする際の設定を行うイメージです.
CarrierWaveではRailsのgenerateコマンドに追加が行われて,
$ rails g uploader [アップローダー名]
が利用できるようになりますのでこれで作成します.
以下のようにしました.
$ rails g uploader MessageImage
アップローダーはapp/uploadersフォルダが新しく作られてそこへまとめられます.
今回生成されたものを見てみると以下のようになっています.
class MessageImageUploader < CarrierWave::Uploader::Base # Include RMagick or MiniMagick support: # include CarrierWave::RMagick # include CarrierWave::MiniMagick # Choose what kind of storage to use for this uploader: storage :file # storage :fog # Override the directory where uploaded files will be stored. # This is a sensible default for uploaders that are meant to be mounted: def store_dir "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end [中略]
store_dirメソッドはファイルの保存先かな?とかある程度想像がつくのでわかりやすそうではあります.
Uploaderとモデルを関連付ける
モデルに画像のパスを保存するので, 今回作成したUploaderとモデルを関連付ける必要があります.
class Message < ApplicationRecord mount_uploader :image_path, MessageImageUploader end
viewの編集
追加側
scaffoldで作ったビュー(_form.html.erb)のファイルパスの部分をfile_fieldに変更.
<div class="field"> <%= form.label :image_path %> <%= form.file_field :image_path, id: :message_image_path %> </div>
表示側
表示側(show.html.erb)も変更.
<p> <strong>Image path:</strong> <%= image_tag(@message.image_path_url) %> </p>
ここまででアップロードと表示ができるようになります.
簡単.
アップロードした画像はpublic/の下にstore_dirメソッド定義通りのパスで作成されていました.
画像をリサイズする
今回は画像の変換にMiniMagickを使うのでコメントを外しておきます.
app/uploader/message_image_uploader.rbを変更.
class MessageImageUploader < CarrierWave::Uploader::Base # Include RMagick or MiniMagick support: # include CarrierWave::RMagick include CarrierWave::MiniMagick process resize_to_fit: [200, 200]
resize_to_fitは縦横比を維持したままリサイズするメソッドです.
上記では200×200のサイズになるようにアップロード時に変換するようにしています.
Module: CarrierWave::MiniMagick
リファレンスを見ると他にもいくつかメソッドがありますがよくわからんなぁと思っていたところ詳しく記載してくださっている方がいらっしゃったのでリンク張っときます.
麺処 まつば - CarrierWave + RMagick 画像のリサイズをまとめてみました
サムネイルを作る
アップロードした画像とは別にサムネイルを作る事もできます.
元々コメントアウトで記述されているのでアンコメントするだけで使えます.
# 以下 # Create different versions of your uploaded files: version :thumb do process resize_to_fit: [50, 50] end
表示するには以下の様にビューを変更します.
app/views/messages/show.html.erbを変更.
<!-- 以下を追加 --> <p> <%= image_tag(@message.image_path_url(:thumb)) %> </p>
[モデル名][画像パス保存の属性名]_urlのメソッドには引数にversionのシンボルが渡せます.
今回は:thumbを追加したので引数にこれを渡す事で作成したサムネイルの画像パスを取得できます.
画像をバリデーションする
拡張子でのバリデーション
こちらもコメントアウトをアンコメントするだけで使えます.試しにpngを禁止してみました.
バリデーションで引っかかるので便利です.
app/uploaders/message_image_uploader.rbを編集.
def extension_whitelist %w(jpg jpeg gif) end
画像サイズでのバリデーション
画像ファイルの上限サイズを指定できます.
app/uploaders/message_image_uploader.rbを編集.
def size_range 1..5.megabytes end
I18Nの対応
エラーのバリデーションメッセージを日本語化したいところです.
公式に記載がありました.
これだけできれば色々できそうです.