目次
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
Railsに画像等のファイルをアップロードする機能を実装するgem「CarrierWave」を使用する際のTipsを纏める。
Railsに画像等のファイルをアップロードする機能を実装するgem「CarrierWave」を使用する際のTipsを纏める。
■ 話の前提
テーブル「users」にフィールド「picture_url」があるという前提。
(picture_urlにはアップロードするファイルのURLが格納される。)
■ モデルに関するTip
acts_as_paranoid を併用する場合の注意点
Railsに論理削除を実装できるgem「acts_as_paranoid」を導入しているモデルにCarrierWaveを使用する場合は、skip_callback を設定する必要がある。
class User < ActiveRecord::Base
acts_as_paranoid
mount_uploader :picture_url, ImageUploader
skip_callback :commit, :after, :remove_picture_url!
end
※skip_callbackがないと、データベースが更新された後、画像が削除されてしまう。
■ コントローラに関するTip
確認画面が存在する場合の工夫
確認画面がなく、1クリックで更新する様なシステムの場合は非常に単純(編集画面→更新)。
# データベースの更新を行い、指定のディレクトリにファイルを配置する。
@user.save!
しかし、確認画面がある場合は、少し複雑になる(編集画面→確認画面→更新)。
確認画面がある場合は、暗黙的に以下を満足する必要がある事が恐らく一般的である。
- 確認画面にファイルを表示する(画像の場合)。
- 確認画面を表示しただけでは、データベース更新も格納ファイルの変更もしない。
CarrierWaveでは、通常のアップロード(save)以外に、一時的なアップロードを行う事ができるので、その機能を活用する。
※一時的アップロードでは、データベースは更新されず、指定のディレクトリとは別の一時ディレクトリにファイルがキャッシュとして保存される。
確認時のアクション
# 一時的アップロード(@userインスタンスには一時ディレクトリのパスが入る)
@user.picture_url.cache!
確認画面のビュー
<%# 一時ディレクトリの場所にある画像を表示 %>
<%= image_tag(@user.picture_url.url) %>
<%# キャッシュ名(一時ディレクトリの名前)をhiddenで渡す %>
<%= hidden_field_tag :"cache[picture_url]", @user.picture_url.cache_name %>
※アップロードファイルのフィールドが1つの場合はパラメータ名は”cache_picture_url”等でも良いが、この例では複数フィールドがある場合にも対応できる様に配列にしている。
更新時のアクション
# パラメータで受け取ったキャッシュから画像を復元する
@user.picture_url.retrieve_from_cache! params[:cache][:picture_url]
@user.save!
■ ビューに関するTip
form_for, form_tag 使用時の注意点
form_for, form_tagを使用する場合はmutipartオプションが必要である。
<%= form_for(@user, html: { multipart: true }) do |f| %>