Deviseのインストールが済んでいて、registrations#editでユーザーの画像をアップロードしたいという時の流れです。アップローダーのライブラリはcarrierwaveを使っています。
環境はこちらです
1 2 3 4 5 6 |
ruby 2.5.1 rails 5.1.6 docker 18.06.0-ce devise 4.4.3 carrierwave 1.2.3 rmagick 2.16.0 |
準備
必要なgemはこちらです。
Gemfile
1 2 3 |
gem 'devise' gem 'carrierwave' gem 'rmagick' #画像処理に必要 |
$ bundle install します。
DeviseはUserモデルだとして、そこにavatarカラムを追加します。
1 |
$ rails g migration add_avatar_to_users avatar:string |
$ rails db:migrat します。
アップローダー
avatarのアップローダーを生成します。
1 |
$ rails g uploader Avatar |
アップローダーの内容は適宜変更してください。
app/uploaders/avatar_uploader.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
class AvatarUploader < CarrierWave::Uploader::Base include CarrierWave::RMagick # S3にアップロードする場合 if Rails.env.production? || Rails.env.staging? storage :fog else storage :file end # S3のディレクトリ名 def store_dir "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end # デフォルト画像は700x700に収まるようリサイズ process :resize_to_limit => [700, 700] # サムネイル画像 version :thumb do process resize_to_fill: [100, 100] end # 許可する画像の拡張子 def extension_whitelist %w(jpg jpeg gif png) end # 保存するファイルの命名規則 def filename "something.jpg" if original_filename 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 |
モデルとアップローダーを紐づける
使用するモデルに次の一行を追記して、モデルとの紐づけをおこないます。
app/models/user.rb
1 2 3 4 5 |
class User < ApplicationRecord mount_uploader :avatar, AvatarUploader end |
ストロングパラメーターの追加
account_update_paramsにavatar, avatar_cache, remove_avatarを追加します。avatar_cacheはバリデーション時などに画像を保持するためで、remove_avatarは画像を削除する時のためのパラメーターです。
app/controllers/users/registrations_controller.rb
1 2 3 4 5 |
protected def configure_account_update_params devise_parameter_sanitizer.permit(:account_update, keys: [:name, :avatar, :avatar_cache, :remove_avatar]) end |
Views
user/registrations#editへのリンクを貼っておきます。
1 |
<%= link_to '編集', edit_user_registration_path %> |
‘current_user’はサインインしているユーザーを取得するdeviseのヘルパーメソッドです。既存の画像がない場合は’no_avatar.png’という画像をあてています。
app/views/devise/registrations/edit.html.erb
1 2 3 4 5 6 7 8 9 10 |
<div class="circle-avatar"> <% if current_user.persisted? && current_user.avatar? %> <%= image_tag current_user.avatar.to_s %> <label><%= f.check_box :remove_avatar %> 画像を削除</label> <% else %> <%= image_tag 'no_avatar.png' %> <%= f.hidden_field :avatar_cache %> <% end %> <%= f.file_field :avatar %> </div> |
CSS
アバター画像を正円にするために’border-radius’を50%にしています。画像の縦横比を保ちつつ中央にトリミングする方法は色々あるかと思いますが、’object-fit’プロパティーを使えば一行で済みます。
1 2 3 4 5 6 |
.circle-avatar img { width: 100px; height: 100px; border-radius: 50%; object-fit: cover; } |
リダイレクト先
Deviseのアカウント情報を更新した後のリダイレクト先はデフォルトではroot_pathになっているかと思いますが、指定するには after_update_path_forを使います。
app/controllers/users/registrations_controller.rb
1 2 3 4 5 |
protected def after_update_path_for(resource) account_page_path end |
今回は以上です!続編では、アップロードした画像をすぐにプレビューできるようにjQueryを追加したいと思います!😊
アップロードした画像を即時プレビューする