##CarrierWaveで画像のアップロード機能を実装する
今回はユーザーテーブルにプロフィール画像を設定できるようにします。
###1. モデルに画像アップロード用のカラムを設定する
userモデルに画像をアップロードするためのimageカラムを追加します。
$ rails g migration add_image_column_to_users image:string
マイグレーションファイルの内容を適用します。
$ rails db:migration
もしすでにデータベース内にimageカラムを持っていないユーザーデータが存在しているなら、データベースの中身を一度リセットする必要があります。
$ rake db:migrate:reset
###2. Gemfileにcarrierwaveを追加してbundle installを実行
gem 'carrierwave'
$ bundle install
サーバーの再起動も忘れないように、このタイミングで。(基本いつでも大丈夫)
rails s
###3. rails g uploader imageで画像のアップローダークラスを作成
$ rails g uploader image
これで画像をアップロードできるようになります。
###4. アップローダを実装したいクラスに以下のコードを追加
mount_uploader :image, ImageUploader
###5. Strong Parameterにimageカラムを追加
def user_params
params.require(:user).permit(:name, :email, :image)
end
これで画像をアップロードする準備が整いました、あとはviewを記述するだけです。
###6. 画像の表示・投稿するためのviewを記述
画像表示するためのview
<% if @user.image? %>
<%= image_tag @user.image.url %>
<% end %>
画像を投稿するためのview
<%= f.label :image %>
<%= f.file_field :image %>
これで画像の表示・投稿機能が完成しました!
アップロードした画像はpublicフォルダ内に格納されていました。しかしこのままではアップロードしたときの画像名・大きさでフォルダ内に保存されるので、画像の加工を行うgemのrmagickを利用します。
##rmagicで画像の加工を行う
rmagickのgemをインストールするにはimageMagickがインストールされていないといけないそうです。
imageMagickがインストールされているかは以下のコマンドで確認できます。
$ convert -version
もしインストールされていなかったらimageMagickをインストールしてください。Macの場合はbrewを使えばインストールできるそうです。
$ brew install imagemagick@6
###1. Gemfileにrmagickを追加してbundle installを実行します
gem 'rmagick'
$ bundle install
サーバーの再起動も忘れないでね
###2. image_uploader.rbで設定を記述する
画像をどのような形式に加工するかは、/app/uploaders/image_uploader.rbで設定できます。
デフォルトでは以下のようになっています、このファイルを編集していきます。
class ImageUploader < 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
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url(*args)
# # For Rails 3.1+ asset pipeline compatibility:
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
#
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
# end
# Process files as they are uploaded:
# process scale: [200, 300]
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
# version :thumb do
# process resize_to_fit: [50, 50]
# end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
# def extension_whitelist
# %w(jpg jpeg gif png)
# end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
end
変更を加えたファイルはこのようになりました。
class ImageUploader < CarrierWave::Uploader::Base
# リサイズしたり画像形式を変更するのに必要
include CarrierWave::RMagick
# 画像の上限を640x480にする
process :resize_to_limit => [640, 480]
# 保存形式をJPGにする
process :convert => 'jpg'
# サムネイルを生成する設定
version :thumb do
process :resize_to_limit => [300, 300]
end
version :thumb100 do
process :resize_to_limit => [100, 100]
end
version :thumb30 do
process :resize_to_limit => [30, 30]
end
# jpg,jpeg,gif,pngしか受け付けない
def extension_white_list
%w(jpg jpeg gif png)
end
# 拡張子が同じでないとGIFをJPGとかにコンバートできないので、ファイル名を変更
def filename
super.chomp(File.extname(super)) + '.jpg' if original_filename.present?
end
# ファイル名を日付にするとタイミングのせいでサムネイル名がずれる
#ファイル名はランダムで一意になる
def filename
"#{secure_token}.#{file.extension}" if original_filename.present?
end
protected
def secure_token
var = :"@#{mounted_as}_secure_token"
model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid)
end
end
これで完了です!
###参考
https://pg-happy.jp/carrierwave-rmagic-uploader.html
https://nyoken.com/rails-carrierwave
image_uploader.rbについて
http://www.workabroad.jp/tech/1118
https://qiita.com/tackey/items/ba68ca8489500b7cb739