プロフィール編集画面
実装内容
プロフィール詳細ページ(/profile)と編集ページ(/profile/edit)を作成する
プロフィール編集画面からアバター画像をアップロードできるようにし、プロフィール詳細画面、ヘッダーアイコン、コメントしたユーザーのアイコン画像が表示されるようにする。
画像のカラムを作成
usersテーブルにavatar
カラムを追加
$ rails g migration add_avatar_to_users avatar:string
$ rails db:migrate == 20210623060835 AddAvatarToUsers: migrating ================================= -- add_column(:users, :avatar, :string) -> 0.0014s == 20210623060835 AddAvatarToUsers: migrated (0.0017s) ========================
$ rails g uploader avatar create app/uploaders/avatar_uploader.rb
モデルと紐付け
mount_uploader :avatar, ImageUploader
uploader.rb
の編集
include CarrierWave::MiniMagick def store_dir "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end def default_url(*args) 'sample.jpg' end def extension_allowlist %w(jpg jpeg gif png) end
ルーティング
resource :profile, only: %i[show edit update]
resourcesとresourceメソッド
プロフィールはユーザーに対して1つしか存在しなく、idを表示させると他のユーザーのプロフィールを編集できてしまうので表示しないように設定。
resources
ではなくresource
を使う。
resourceを使うことでid付きでURLが生成されなくなる。
resourceの場合
edit_profile GET /profile/edit(.:format) profiles#edit
profile GET /profile(.:format) profiles#show
PATCH /profile(.:format) profiles#update
PUT /profile(.:format) profiles#update
resourcesの場合
edit_profile GET /profile/:id/edit(.:format) profile#edit
profile GET /profile/:id(.:format) profile#show
PATCH /profile/:id(.:format) profile#update
PUT /profile/:id(.:format) profile#update
controller
profilesコントローラーの作成
$ rails g controller profiles
ストロングパラメータにavatarを追加。
class ProfilesController < ApplicationController def show; end def edit @user = User.find(current_user.id) end def update @user = User.find(current_user.id) if @user.update(user_params) redirect_to profile_path, success: 'ユーザーを更新しました' else flash.now['danger'] = 'ユーザーを更新できませんでした' render :edit end end private def user_params params.require(:user).permit(:email, :first_name, :last_name, :avatar) end end
view
プロフィール詳細、編集画面のviewを作成
<% content_for(:title, t('.title')) %> <div class="container pt-3"> <div class="row"> <div class="col-md-10 offset-md-1"> <h1 class="float-left mb-5"><%= t('.title')%></h1> <%= link_to '編集', '/profile/edit', class: 'btn btn-success float-right' %> <table class="table"> <tr> <th scope="row">メールアドレス</th> <td><%= current_user.email %></td> </tr> <tr> <th scope="row">氏名</th> <td><%= current_user.decorate.full_name %></td> </tr> <tr> <th scope="row">アバター</th> <td><%= image_tag current_user.avatar.url, class: 'rounded-circle mr15', size: '50x50' %></td> </tr> </table> </div> </div> </div>
<% content_for(:title, t('.title')) %> <div class="container pt-3"> <div class="row"> <div class="col-md-10 offset-md-1 mb-5"> <h1 class="float-left"><%= t('.title')%></h1> </div> <div class="col-md-10 offset-md-1"> <%= form_with model: @user, url: profile_path, local: true do |f| %> <%= render "shared/error_messages", object: f.object %> <div class="form-group"> <%= f.label :email %> <%= f.email_field :email, class: "form-control" %> </div> <div class="form-group"> <%= f.label :last_name %> <%= f.text_field :last_name, class: "form-control" %> </div> <div class="form-group"> <%= f.label :first_name %> <%= f.text_field :first_name, class: "form-control" %> </div> <div class="form-group"> <%= f.label :avatar %> <%= f.file_field :avatar, class: "form-control", accept: 'image/*', onchange: 'previewFileWithId(preview)' %> <%= f.hidden_field :avatar_cache %> <div class='mt-3 mb-3'> <%= image_tag @user.avatar.url , size: '100x100', class: 'rounded-circle' %> </div> </div> <%= f.submit class: "btn btn-primary"%> <% end %> </div> </div> </div>
ヘッダーアイコン、コメントフォームに設定した画像を表示させる
ヘッダーはログイン中のユーザー
<%= image_tag current_user.avatar_url, size: '40x40', class: 'rounded-circle mr15'%>
コメントフォームはコメントしたユーザーのアイコンを表示
<%= image_tag comment.user.avatar_url, class: 'rounded-circle', size: '50x50' %>
i18n追記
profiles: edit: title: 'プロフィール編集' show: title: 'プロフィール' email: 'メールアドレス' name: '氏名' avatar: 'アバター'