Ruby on Rails 入門5

今回はプロフィール画面を充実させていこうと思います

完成形

スクリーンショット 2020-02-23 16.50.26

Gemfile

画像の処理でrefileというgemを使う

# 末尾に追記
gem 'refile', require: 'refile/rails', github: 'refile/refile', branch: 'master'
gem 'refile-mini_magick'
$ bundle install

imagemagickのインストール(Ubuntu)

$ sudo apt-get install imagemagick

カラム追加

$ rails g migration AddNameToUsers name:string profile_image_id:string introduction:text
     invoke  active_record
     create    db/migrate/20200223061845_add_name_to_users.rb
$ rake db:migrate
== 20200223061845 AddNameToUsers: migrating ===================================
-- add_column(:users, :name, :string)
  -> 0.0122s
-- add_column(:users, :profile_image_id, :string)
  -> 0.0030s
-- add_column(:users, :introduction, :text)
  -> 0.0025s
== 20200223061845 AddNameToUsers: migrated (0.0243s) ==========================

$

app/models/user.rb

カラム名は profile_image_id だけど_idを省略するルール

class User < ApplicationRecord
 # Include default devise modules. Others available are:
 # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
 devise :database_authenticatable, :registerable,
        :recoverable, :rememberable, :validatable
 attachment :profile_image #追記
end
$ rake db:migrate
== 20200223044001 AddColumnUsers: migrating ===================================
-- add_column(:users, :name, :string)
  -> 0.0106s
-- add_column(:users, :profile_image, :string)
  -> 0.0039s
-- add_column(:users, :introduction, :string)
  -> 0.0011s
== 20200223044001 AddColumnUsers: migrated (0.0201s) ==========================

$

確認

name, profile_image_id, introductionを確認する。OK

$ rails dbconsole
SQLite version 3.11.0 2016-02-15 17:29:24
Enter ".help" for usage hints.
sqlite> .mode line
sqlite> select * from users;
                   id = 1
                email = aaa@aaa.com
   encrypted_password = $2a$11$GBcVaUitWID2ferNlzlDdOZJdsMmGth6A6PxjUWjLwfgbVwEXP6.m
 reset_password_token =
reset_password_sent_at =
  remember_created_at =
           created_at = 2020-02-20 04:33:44.764439
           updated_at = 2020-02-20 04:33:44.764439
                 name =
     profile_image_id =
         introduction =
sqlite> .quit
$

app/views/users/edit.html.erb

編集画面を作る。見た目はダサいのが気になるんだけど、一旦放置。機能を作り終えたらやろうかなと思う。

<div class="container">
 <h1>ユーザー情報</h1>
 <div>
   <%= form_for(@user) do |f| %>
     <div class="user-field">
       <p>ニックネーム</p>
       <p><%= f.text_field :name %></p>
     </div>
     <div class="user-field">
       <p>メールアドレス</p>
       <p><%= f.text_field :email %></p>
     </div>
     <div class="user-field">
       <p>紹介文</p>
       <p><%= f.text_area :introduction %></p>
     </div>
     <div class="user-field">
       <p>プロフィール画像</p>
       <p><%= f.attachment_field :profile_image %></p>
     </div>
     <div>
       <p><%= f.submit "保存" %></p>
     </div>
   <% end %>
 </div>
</div>

config/environments/development.rb

コントローラー修正しても再起動しないと反映されないのが面倒だからこれ追加するんだけど、bundle install とか?の実行後はrails s しないといけないかもしれない。厳密にはわからん

  config.reload_classes_only_on_change = false #追記

app/controllers/users_controller.rb

update と ストロングパラメータのお決まりのそれ。失敗時の挙動はなにもかいてないけど後々やると思う。今は正常系だけやっています。

class UsersController < ApplicationController
  ...略

 def update
   # 追記
   @user = User.find(params[:id])
   if @user.update(user_params)
     flash[:notice] = "保存しました"
     redirect_to user_path(@user)
   else
   end
 end

 # 追記: ストロングパラメータに追加したカラムを記載
 def user_params
   params.require(:user).permit(:name, :introduction, :profile_image)
 end
end

app/views/users/show.html.erb

特筆する点はないかな

<div class="container">
 <p id="notice"><%= flash[:notice] %></p>
 <h1>ユーザー情報</h1>
 <div>
   <p><%= link_to "編集", edit_user_path(@user.id) %></p>
   <div class="user-field">
     <p>ニックネーム</p>
     <p><%= @user.name %></p>
   </div>
   <div class="user-field">
     <p>メールアドレス</p>
     <p><%= @user.email %></p>
   </div>
   <div class="user-field">
     <p>紹介文</p>
     <p><%= @user.introduction %></p>
   </div>
   <div class="user-field">
     <p></p>
     <!-- 画像を最大300*300で表示 -->
     <p><%= image_tag attachment_url(@user, :profile_image, :fill, 300, 300, format: "jpg", fallback: "no_image.png") %></p>
   </div>
 </div>
</div>

詳細画面

スクリーンショット 2020-02-23 16.50.26

編集画面

スクリーンショット 2020-02-23 16.52.14

DB確認

こんな感じでnameなどの追加カラムに値が入ってればOK。少し逸れるけど気になったから日本時間にしようと思う。

$ rails dbconsole
SQLite version 3.11.0 2016-02-15 17:29:24
Enter ".help" for usage hints.
sqlite> .mode line
sqlite> select * from users;
                   id = 1
                email = aaa@aaa.com
   encrypted_password = $2a$11$GBcVaUitWID2ferNlzlDdOZJdsMmGth6A6PxjUWjLwfgbVwEXP6.m
 reset_password_token =
reset_password_sent_at =
  remember_created_at = 2020-02-23 07:33:31.417496
           created_at = 2020-02-20 04:33:44.764439
           updated_at = 2020-02-23 07:33:31.420490
                 name = aaa
     profile_image_id = 4a700d6c0582d65f34af3bbac01570cc52a9197e3c6b2e4ec7b641b5f4d1
         introduction = いとうと申します
sqlite>

タイムゾーン

OSのタイムゾーン(Ubuntuの場合)

$ sudo timedatectl set-timezone Asia/Tokyo

config/application.rb

    config.time_zone = 'Asia/Tokyo' #追記
    config.active_record.default_timezone = :local #追記

確認

更新時間が日本時間になっていればおk

$ rails dbconsole
SQLite version 3.11.0 2016-02-15 17:29:24
Enter ".help" for usage hints.
sqlite> .mode line
sqlite> select * from users;
                   id = 1
                email = aaa@aaa.com
   encrypted_password = $2a$11$GBcVaUitWID2ferNlzlDdOZJdsMmGth6A6PxjUWjLwfgbVwEXP6.m
 reset_password_token =
reset_password_sent_at =
  remember_created_at = 2020-02-23 07:33:31.417496
           created_at = 2020-02-20 04:33:44.764439
           updated_at = 2020-02-23 17:07:00.179368
                 name = aaa
     profile_image_id = 4a700d6c0582d65f34af3bbac01570cc52a9197e3c6b2e4ec7b641b5f4d1
         introduction = いとうと申しますs
sqlite>.quit

あ、あと

ヘッダーのリンクをTop → Homeへ変更しました。

<!DOCTYPE html>
<html>
 <head>
   <title>RailsApp</title>
   <%= csrf_meta_tags %>
   <%= csp_meta_tag %>

   <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
   <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
 </head>
 <header id="header" class="">
   <div class="container">
     <a href="/home" title="Home" class="top">Home</a> <!-- 修正 -->
     <nav>
       <ul>
         <% if user_signed_in? %>
           <li>
             <%= link_to current_user.email, user_path(current_user.id), title: "ユーザ画面" %>
           </li>
         <% end %>
       </ul>
     </nav>
   </div>
 </header>
 <body>
   <%= yield %>
 </body>
</html>

忘れずにGit作業

$ git status # 修正ファイルなどの確認
$ git add .
$ git commit -m "update: add users coloum, image upload"

これでユーザー詳細と更新機能ができた(画像アップロードも含め)。次回何やろうかなー、、、ユーザー画面のレイアウトか、つぶやき機能をつくるかのどっちか

追記

デザインやりました。少しはまともになりました。