Devise Userまでインストールしていることが前提
- gem 'devise'
- gem 'devise-i18n'
- gem 'devise-i18n-views'
$ bundle
$ rails g devise:install
$ rails g devise user
$ rails g devise:controllers users
$ rails g devise:i18n:views user
前提終わり
名前欄と画像欄を追加する
$ rails g migration AddNameToUsers name:string
$ rails g migration AddAvatarToUsers avatar:string
$ rails g uploader Avatar
$ rails db:migrate
controllerに追加する
app/controllers/application_controller.rb
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
devise_parameter_sanitizer.permit(:account_update, keys: [:name])
devise_parameter_sanitizer.permit(:account_update, keys: [:avatar, :avatar_cache, :remove_avatar])
end
他のサイトでは、user_controller.rbに入れていたけど、それだと動かなかった。
userと関連付け
app/models/user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
# ユーザー画像を関連付け
mount_uploader :avatar, AvatarUploader
end
uploaderの設定
app/uploader/avatar_uploader.rb
class AvatarUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
if Rails.env.development?
# ローカルに保存する
storage :file
elsif Rails.env.test?
# ローカルに保存する
storage :file
else
# S3などの外部に保存する
storage :fog
end
# S3のディレクトリ名
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# 許可する画像の拡張子
def extension_whitelist
%w(jpg jpeg gif png)
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
# 画像サムネイル
version :thumb do
process resize_to_fill: [316, 316]
end
# アップロードの時点で指定サイズに収まるようにしておく
process :resize_to_limit => [700, 700]
end
ユーザー編集画面に追加
app/users/registrations/edit.html.erb
<div class="field">
<% if current_user.persisted? && current_user.avatar? %>
<%= image_tag(current_user.avatar.to_s, :class => "img-fluid", :alt => "ユーザーアバター") %>
<label><%= f.check_box :remove_avatar %> 画像を削除</label>
<% else %>
<%= image_tag("favicon.png", :class => "img-thumbnail", :size => "230x230", :alt => "アイコン") %>
<%= f.hidden_field :avatar_cache %>
<% end %>
<div class="input-group input-group-sm mb-3">
<div class="input-group-prepend">
<span class="input-group-text">アップロード</span>
</div>
<div class="custom-file">
<%= f.file_field :avatar, class: 'custom-file-input' %>
<label class="custom-file-label" for="customFile" data-browse="参照">ファイル選択...</label>
</div>
</div>
</div>
user show.html.erbを作っておけばユーザー詳細画面にも表示できる。
Bootstrap4を入れておけば、デザインも楽です。