アバター画像をアップロードできるようにします。
コマンド
rails g migration AddImageColumsToUser image
コマンド
rails active_storage:install
コマンド マイグレーションの適用
rails db:migrate
「app\models\user.rb」ファイルに記述を追加します。
記述追加 app\models\user.rb
3行目に「has_one_attached :avatar」の記述を追加しています。
class User < ApplicationRecord has_one_attached :avatar # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable, :confirmable validates :full_name, presence: true, length: {maximum: 50} end
ユーザーストロングパラメータに「, :avatar」の記述を追加します。
記述追加 app\controllers\users_controller.rb
21行目に「, :avatar」の記述を追加しています。
カンマを忘れないようにして下さい。
class UsersController < ApplicationController before_action :authenticate_user! def dashboard end def update @user = current_user if @user.update_attributes(current_user_params) flash[:notice] = "保存しました" else flash[:alert] = "更新できません" end redirect_to dashboard_path end private def current_user_params params.require(:user).permit(:about, :status, :avatar) end end
アバター画像用のヘルパーを追加します。
記述更新 app\helpers\application_helper.rb
module ApplicationHelper def avatar_url(user) if user.avatar.attached? url_for(user.avatar) elsif user.image? user.image else ActionController::Base.helpers.asset_path('icon_default_avatar.jpg') end end end
ダッシュボードビューに記述を追加します。
1.16行目の「<%= image_tag 'icon_default_avatar.jpg' %>」の記述を以下の記述に書き換えます。
<%= image_tag avatar_url(current_user), class: "is-rounded" %>
2.記述追加 app\views\users\dashboard.html.erb(27行目)
26行目の記述を削除して置き換えます。
<%= form_for :user, url: users_edit_url(@user), action: :update, method: :post do |f| %> <div class="file"> <label class="button is-primary is-outlined is-fullwidth"> <%= f.file_field :avatar, class: "file-input", onchange: "this.form.submit();" %> <i class="fas fa-upload"></i> アバター画像アップロード </label> </div> <% end %>
記述更新 app\views\users\dashboard.html.erb
コードをコピーしてファイルの内容を置き換えて下さい。
<section class="section"> <div class="container"> <div class="columns"> <!-- 左パネル --> <div class="column is-one-third"> <div class="columns is-multiline"> <!-- 上部 --> <div class="column is-full"> <div class="card"> <!-- アバター --> <div class="card-content is-horizontal-center is-flex"> <figure class="image is-256x256"> <%= image_tag avatar_url(current_user), class: "is-rounded" %> </figure> </div> <div class="card-content"> <!-- 画像アップロードボタン --> <div class="content has-text-centered"> <p class="title is-5"> <%= current_user.full_name %> </p> <%= form_for :user, url: users_edit_url(@user), action: :update, method: :post do |f| %> <div class="file"> <label class="button is-primary is-outlined is-fullwidth"> <%= f.file_field :avatar, class: "file-input", onchange: "this.form.submit();" %> <i class="fas fa-upload"></i> アバター画像アップロード </label> </div> <% end %> </div> <hr class="h-10"> <!-- アカウント情報 --> <article class="media"> <div class="media-content">アカウント登録日</div> <div class="media-right"> <strong><%= I18n.l(current_user.created_at, format: :full_date) %></strong> </div> </article> <hr class="h-10"> <!-- オンラインステータス --> <article> <div class="media"> <div class="media-content">ステータス</div> <div class="media-right"> <strong><% if current_user.status %> オンライン <% else %> オフライン <% end %></strong> <i class="toggle far fa-edit" aria-controls="user-status"></i> </div> </div> <div class="content"> <%= form_for :user, url: users_edit_url(@user), action: :update, method: :post, html: {id: 'user-status', class: 'is-hidden'} do |f| %> <div class="field"> <%= f.select(:status, options_for_select([["オンライン", true], ["オフライン", false]]), {}, {class: "select is-fullwidth"}) %> </div> <a class="toggle button is-light" aria-controls="user-status">キャンセル</a> <%= f.submit "保存", class: "button is-danger" %> <% end %> </div> </article> </div> </div> </div> <!-- 下部 --> <div class="column is-full"> <div class="card"> <div class="card-content"> <!-- アカウント詳細 --> <article> <div class="media"> <div class="media-content"> <p> <strong>自己紹介</strong> <br> <%= current_user.about %> </p> </div> <div class="media-right"> <i class="toggle far fa-edit" aria-controls="user-about"></i> </div> </div> <div class="content"> <%= form_for :user, url: users_edit_url(@user), action: :update, method: :post, html: {id: 'user-about', class: 'is-hidden'} do |f| %> <div class="field"> <%= f.text_area :about, autofocus: true, autocomplete: 'form', class: 'input'%> </div> <a class="toggle button is-light" aria-controls="user-about">キャンセル</a> <%= f.submit "保存", class: "button is-danger" %> <% end %> </div> </article> <hr class="h-10"> <!-- 電話番号 --> <article class="media"> </article> </div> </div> </div> </div> </div> <!-- 右側 --> <div class="column"> <div class="columns is-multiline"> <!-- 新しい部屋を登録 --> <div class="column is-one-third has-text-centered"> </div> <!-- 登録したお部屋--> <div class="column is-one-third has-text-centered"> </div> </div> </div> </div> </div> </section>
ナビゲーションバーを更新します。
記述追加 app\views\shared\_navbar.html.erb(35行目)
<figure class="image is-48x48 m-r-5"> <div style="margin-top: 0.6rem;"> <%= image_tag avatar_url(current_user), class: "is-rounded" %> </div> </figure>
app\views\shared\_navbar.html.erb
<nav class="navbar is-light" role="navigation" aria-label="main navigation"> <div class="navbar-brand"> <a class="navbar-item" href="/"> <h1>テストサイトMinpaku6</h1> </a> <a role="button" class="navbar-burger burger" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample"> <span aria-hidden="true"></span> <span aria-hidden="true"></span> <span aria-hidden="true"></span> </a> </div> <div id="navbarBasicExample" class="navbar-menu"> <div class="navbar-start"> <div class="navbar-item"> </div> </div> <div class="navbar-end"> <a class="navbar-item"></a> <a class="navbar-item"></a> <!-- もしログインしていなかったら--> <% if (!user_signed_in?) %> <div class="navbar-item"> <div class="buttons"> <%= link_to "新規ユーザ登録", new_user_registration_path, class: "button is-white" %> <%= link_to "ログイン", new_user_session_path, class: "button is-white" %> </div> </div> <!-- ログインしていたら --> <% else %> <div class="navbar-item has-dropdown is-hoverable" style="margin-right: 100px;"> <a class="navbar-item"> <figure class="image is-48x48 m-r-5"> <div style="margin-top: 0.6rem;"> <%= image_tag avatar_url(current_user), class: "is-rounded" %> </div> </figure> <%= current_user.full_name %> </a> <div class="navbar-dropdown"> <%= link_to "ユーザ登録情報編集", edit_user_registration_path, class: "navbar-item" %> <a href="" class="navbar-item"></a> <hr class="navbar-divider"> <%= link_to "ログアウト", destroy_user_session_path, method: :delete, class: "navbar-item" %> </div> </div> <% end %> </div> </div> </nav> <% if (user_signed_in?) %> <nav class="navbar has-shadow" style="z-index: 3;"> <div class="container"> <div class="navbar"> <%= link_to 'ダッシュボード', dashboard_path, class: "navbar-item" %> <div class="navbar-item has-dropdown is-hoverable"> <a class="navbar-link">ホスト</a> <div class="navbar-dropdown"> <a class="navbar-item"></a> <a class="navbar-item"></a> </div> </div> <div class="navbar-item has-dropdown is-hoverable"> <a class="navbar-link">ゲスト</a> <div class="navbar-dropdown"> <a class="navbar-item"></a> <a class="navbar-item"></a> </div> </div> </div> </div> </nav> <% end %> <script> $(document).ready(function() { // navbar burgerアイコンでクリックイベントを確認する $(".navbar-burger").click(function() { // 「navbar-burger」と「navbar-menu」の両方で「is-active」クラスを切り替える $(".navbar-burger").toggleClass("is-active"); $(".navbar-menu").toggleClass("is-active"); }); }); </script>
ブラウザ確認
http://localhost:3000/dashboard
ドロップダウンメニューにアバター画像をつけました。
アバター画像をアップロードできるか確認して下さい。