A Little Each Day

note to self

carrierwaveの便利な機能の使い方まとめ

こんにちは。本日はcarrierwaveで用意されてる便利な機能をいくつか紹介していきたいと思います。

carrierwaveにはデフォルトで画像の設定に関して便利な機能がいくつも用意されています。

今回はよく使うであろう機能をまとめてみました。

画像の拡張子の制限

ファイルには拡張子の種類がたくさんありますが、アップロードする画像の拡張子を制限したいと思うことがあると思います。

carrierwaveではそれを簡単に実装することができます。

アップローダー用のファイルにあるコメントになっている部分をコメントアウトするだけです。

# app/uploaders/picture_uploader.rb

  def extension_white_list
    %w(jpg jpeg gif png)
  end


これだけでファイルの拡張子の制限ができてしまいます。
この場合は jpg,jpeg,gif,png の拡張子だけを許可します。


拡張子の種類を指定する

投稿した画像の拡張子を保存するときに指定した拡張子にすることもできます。

やり方は簡単でアップローダーファイルに指定したい拡張子を記載しするだけです。

# picture_uploader.rb

  process :convert => 'jpg'


この場合は投稿した画像が保存された時に「jpg」に拡張子を変えてくれます。


画像のリサイズ

画像をアップロードするうえで、あまりにも大きなサイズの画像を投稿されてしまうとレイアウトが崩れてしまいますよね。

そこでcarrierwaveには簡単に画像のリサイズができる機能が用意されています。

しかしながら、それを実装するために下準備がいくつかあるので順番に見ていきましょう。


まずはじめに画像をリサイズするためにImageMagickという画像操作プログラムをインストールします。

今回はhomebrewを使ってインストールします。

$ brew install imagemagick


次にImageMagickを使えるようにするためにMiniMagickをGemに記載します。

# Gemfile

gem 'mini_magick'


インストール

$ bundle install


そしてMiniMagickに対応させるためにアップローダーファイルを編集します。

とはいえ、こちらもコメントアウトするだけです。

#app/uploaders/picture_uploader.rb

# 以下のコメントをコメントアウト
include CarrierWave::MiniMagick


以上で下準備は完了です。


※ファイルサイズのバリデーションはこちらを参考にしてください。

blog.otsukasatoshi.com


下準備が終わったので実際に投稿していきましょう。


今回はindexページにサムネイル、showページに大きな画像を表示したいと思います。

まずアップローダーファイルに画像の大きさを指定しましょう。こちらもコメントアウトされているので解除しましょう。

#app/uploaders/picture_uploader.rb

  # showページ(大きな画像)
  process :resize_to_fit => [200,200]

  # indexページ(サムネイル)
  version :thumb do
    process :resize_to_fit => [50,50]
  end


これで画像のリサイズができたはずです。

# app/posts/index.html.erb

  # 表示したいところに記載 
  <%= image_tag post.picture.url(:thumb) %>
# app/posts/show.html.erb

  # 表示したいところに記載 
  <%= image_tag @post.picture.url %>


それでは実際に投稿してみて確認しましょう。


show.html.erbの場合

f:id:chi_kun:20160515145400p:plain


index.html.erbの場合

f:id:chi_kun:20160515145420p:plain


きちんと同じ画像がそれぞれリサイズされていて、showページでは大きな画像、indexページではサムネイルが表示されていると思います。


バリデーションエラー時に画像を保持

画像を投稿した際、もしもバリデーションに引っかかった場合(名前とか内容が空だったり)で、carrierwaveはデフォルトでは画像のキャッシュが残りません。

なのでバリデーションに引っかかった時に再度投稿フォームが表示されますが、投稿したはずの画像はフォーム上に表示されません。

これだとユーザーがちょっと戸惑ってしまうと思うのですが、実はcarrierwaveでは簡単に画像のキャッシュの設定ができます。


まずcontrollerのストロングパラメーターの箇所でcacheを受け取るように追加します。

# posts_controller.rb

  private

  def post_params
    params.require(:post).permit(:picture, :title, :content, :picture_cache)
  end


そして画像を保持したい該当のフォームにimage_tagとhidden_fieldを書きます。ここにバリデーションに引っかかった場合に画像が表示されます。

# _form.html.erb

  <div class="field">
    # ここから追加 
    <%= image_tag @post.picture.url(:thumb) if @post.picture? %>
    <%= f.hidden_field :picture_cache %>
    # ここまで追加 
    <%= f.label :picture %>
    <%= f.file_field :picture %>
  </div>


では実際に投稿してみましょう。

今回はあえてバリデーションに引っかかってみます。

f:id:chi_kun:20160516154851p:plain


すると一度投稿した画像がきちんと表示されているとおもいます。


画像が横回転するのを防ぐ

「画像が横回転する?どういうこと?」と思った方がいると思うのですが実際に例を見てみましょう。

f:id:chi_kun:20160516160752p:plain


これは画像を普通に投稿して成功した場合です。画像によっては、なぜか画像が横向きになってしまいます。投稿時だけでなく編集時にも同じ現象が発生します。

これを解消するために、アップローダーファイルに全ての画像を縦回転(横向きではなく)になるように編集を加えます。

# picture_uploader.rb

  # 画像の横回転を防ぐ 
  process :fix_rotate
  def fix_rotate
    manipulate! do |img|
      img = img.auto_orient
      img = yield(img) if block_given?
      img
    end
  end


これで投稿時や編集時に画像が横になることがなく、きちんと縦向きになります。


それでは実際に投稿して見ましょう。

f:id:chi_kun:20160516162011p:plain


きちんと画像が縦向きになりましたね!(もちろん上記と同じ画像です。)



本日は以上です。