見出し画像

railsチュートリアル魔改造編 第19章 プロフィール魔改造

第19章 プロフィール改造編

プロフィールを魔改造していきます。

いつものようにトピックブランチを作成します。

cd ‾/environment/sample_app
git checkout -b rails-makaizou-19

19.1 プロフィール画面はどこから飛ぶ?

/sample_app/app/controllers/sessions_controller.rb
のcreateアクションで、redirect_back_orを使ってログインしている。
redirect_back_orというメソッドがあるが、これの定義は
/sample_app/app/helpers/sessions_helper.rb
にある。
前のページを保存していたらそのページを表示し、そうでないならプロフィール画面に飛ぶメソッドである。

まずはroutes.rbを開く。
プロフィール画面は/users/1とかで開く。
このURLを作り出しているのは下記の部分。
resources :users

これにより、redirect_to user
とすると、users/1というURLでusers_controllerのshowアクションが呼ばれ、/sample_app/app/views/users/show.html.erbが表示される


19.2 ヘッダー魔改造

ログイン状態だとヘッダーに表示するものが変わるので、まずはこの表示を変更する。
すべて
/sample_app/app/views/layouts/_header.html.erb
で変えられる

19.2.1 Usersをユーザーを探すにする

Usersと直書きされているのでユーザーを探すに変更

19.2.2 Accountをユーザー名にする

/sample_app/app/views/layouts/_header.html.erb
で変更

Accountだと分かりづらい気がしたのでユーザー名に変更した
アカウント名は<%= current_user.name %>とすればよい。

19.2.3 Profileをプロフィールにする

/sample_app/app/views/layouts/_header.html.erb
で変更


19.2.4 Settingを設定にする

/sample_app/app/views/layouts/_header.html.erb
で変更


19.3 フォロー中/フォロワー

followingをフォロー中にし、
followersをフォロワーにする。

それぞれを表示しているのは
/sample_app/app/views/shared/_stats.html.erb
である。


19.3.1 followingをフォロー中にする

/sample_app/app/views/shared/_stats.html.erb
で変更。

19.3.2 followersをフォロワーにする

/sample_app/app/views/shared/_stats.html.erb
で変更。

19.5 Microposts(x)をツイートxにする

Microposts(x)と表示しているのは
/sample_app/app/views/users/show.html.erb
である。
ツイートに変更する。

will_paginateのおかげで表示されているボタンの英文字は変更するのを断念

19.6 posted x agoを日本語にする

ここは中途半端であるが、
12 minutes 前とか、
13 days 前とかに表示を変更する。

minutesとかdaysはgemfileで対応可能。
今回はあえて対応しなかった。

/sample_app/app/views/microposts/_micropost.html.erb
で変更した。

19.7 deleteをツイートを削除にする

deleteという文字列を表示しているのは
/sample_app/app/views/microposts/_micropost.html.erb
である。変更する。

ここで、テストが失敗するはずなので、

/sample_app/test/integration/microposts_interface_test.rb
の該当の行をコメントアウトする。

これでテストが成功するはずである。

19.8 Follow/Unfollowをフォロー/フォロー解除にする

/sample_app/app/views/users/_follow_form.html.erb
で、ログイン中のユーザーかそうでないかでボタンの表示・非表示が切り替わる

/sample_app/app/views/users/_follow.html.erb
で、フォローボタンが出る

/sample_app/app/views/users/_unfollow.html.erb
で、フォロー解除ボタンがでる。

それぞれ変更。

19.9 ツイート削除時のメッセージを変更

削除時、
/sample_app/app/views/microposts/_micropost.html.erb
のrink_toから
/sample_app/app/controllers/microposts_controller.rb
のdestroyメソッドを呼び出している。
そこでメッセージを変更できる。
redirect_to request.referrer || root_urlというのがあるが、これは
1つ前のページを返すか、見つからなければルートurlを表示するものである。

19.10 最後に

保存する

rails test
git add -A
git status

ログ
----------------------------
modified:   app/controllers/microposts_controller.rb
modified:   app/controllers/sessions_controller.rb
modified:   app/controllers/users_controller.rb
modified:   app/helpers/sessions_helper.rb
modified:   app/models/micropost.rb
modified:   app/models/user.rb
modified:   app/views/layouts/_header.html.erb
modified:   app/views/microposts/_micropost.html.erb
modified:   app/views/shared/_stats.html.erb
modified:   app/views/users/_follow.html.erb
modified:   app/views/users/_follow_form.html.erb
modified:   app/views/users/_unfollow.html.erb
modified:   app/views/users/show.html.erb
modified:   config/routes.rb
modified:   test/integration/microposts_interface_test.rb
----------------------------

15ファイル修正したことを確認

git commit -m "add 19"
git checkout master
修正前ファイルをブログ用に保存しておく
git merge rails-makaizou-19
git push origin master
修正後ファイルをブログ用に保存しておく

そしてherokuの操作
source <(curl -sL https://cdn.learnenough.com/heroku_install)
git remote set-url heroku https://git.heroku.com/jun-killer-makaizou.git
heroku maintenance:on
git push heroku master
heroku maintenance:off

https://jun-killer-makaizou.herokuapp.com/

19.10.1 修正後


リスト19.01
app/controllers/microposts_controller.rb
----------------------------
class MicropostsController < ApplicationController
 before_action :logged_in_user, only: [:create, :destroy]
 before_action :correct_user,   only: :destroy
 def create
   @micropost = current_user.microposts.build(micropost_params)
   if @micropost.save
     flash[:success] = "Micropost created!"
     redirect_to root_url
   else
     @feed_items = []
     render 'static_pages/home'
   end
 end
 #/sample_app/app/views/microposts/_micropost.html.erbから呼ばれる
 def destroy
   @micropost.destroy
   flash[:success] = "ツイートを削除しました"
   #1つ前のページを返すか、見つからなければルートurlを表示
   redirect_to request.referrer || root_url
 end
 private
   def micropost_params
     params.require(:micropost).permit(:content, :picture)
   end
   def correct_user
     @micropost = current_user.microposts.find_by(id: params[:id])
     redirect_to root_url if @micropost.nil?
   end
end

リスト19.02
app/controllers/sessions_controller.rb
----------------------------
class SessionsController < ApplicationController
 #ログイン画面が表示されたときは、アクションで特になにもしない
 #/sample_app/config/routes.rbによって/loginで飛ぶ
 def new
 end
 #ログイン画面でログインボタンを押したときに実行されるアクション
 #/sample_app/config/routes.rbによって/loginから飛ぶ
 def create
   # テーブルからユーザー情報を取得する
   user = User.find_by(email: params[:session][:email].downcase)
   
   # ユーザーが存在しており、かつパスワードが合っている場合
   if user && user.authenticate(params[:session][:password])
     # ユーザーが有効化されいる場合
     if user.activated?
       log_in user
       params[:session][:remember_me] == '1' ? remember(user) : forget(user)
       flash[:success] = user.name+'さん、おかえりなさい!'
       
       #redirect_back_orとは?
       #/sample_app/app/helpers/sessions_helper.rbに定義がある
       #前ページの保存が無ければuserに飛ぶ
       #userで単数形にするとusers/1とかに飛ぶ
       #なんでかっていうとconfig/routes.rbでresource userで自動でidつきのurlになるから
       # /sample_app/app/controllers/users_controller.rbのshowアクションが呼ばれる
       redirect_back_or user
     # ユーザーが有効化されいない場合
     else
       message  = "アカウントが承認されていないようです。\n"
       message += "お手数ですが、メールアドレスからアカウントの承認をお願いします。"
       
       #再表示の場合は、flashではなくflash.nowにする
       flash.now[:warning] = message
       
       #再表示
       render 'new'
     end
   #ユーザーが存在していない場合または
   else
     flash.now[:danger] = 'メールアドレスまたはパスワードに誤りがあります'
     render 'new'
   end
 end
 def destroy
   log_out if logged_in?
   redirect_to root_url
 end
end
リスト19.03
app/controllers/users_controller.rb
----------------------------
class UsersController < ApplicationController
 before_action :logged_in_user, only: [:index, :edit, :update, :destroy,
                                       :following, :followers]
 before_action :correct_user,   only: [:edit, :update]
 before_action :admin_user,     only: :destroy
 
 def index
   @users = User.where(activated: true).paginate(page: params[:page])
 end
 #/users/1とかで呼ばれるアクション
 def show
   #userの情報を取得する
   @user = User.find(params[:id])
   #userの持つmicropostを取得する
   #paginateメソッドとシンボルとparamsは
   @microposts = @user.microposts.paginate(page: params[:page])
   #/sample_app/app/views/users/show.html.erbへ
 end
 
 # /signup で呼ばれるアクション
 # app/views/users/new.html.erbへ
 def new
   #ユーザーを新規に作成する
   @user = User.new
 end
 
 # app/views/users/new.html.erbでform_forによって送信を押した後に呼ばれる
 def create
   #入力フォームに入力された値でユーザーデータを作成する
   #user_paramsは同ファイルのprivateに定義がある
   #user_paramsはStrongParameterが返ってくる
   @user = User.new(user_params)
   
   #セーブに成功した?
   if @user.save
     #メールを送信する
     #send_activation_emailの定義はapp/models/user.rbにある
     #メールの内容は以下で編集できる
     #app/views/user_mailer/account_activation.html.erb
     #app/views/user_mailer/account_activation.text.erb
     @user.send_activation_email
     #メールを送信したことを通知する
     flash[:info] = @user.email+"にメールを送信しました。お手数ですが、承認をお願いします。"
     #トップページに移行する
     redirect_to root_url
   #セーブに失敗した?
   else
     #再度入力をお願いする
     #エラー文は自動的に出るようになってる
     render 'new'
   end
 end
 def edit
 end
 def update
   if @user.update_attributes(user_params)
     flash[:success] = "Profile updated"
     redirect_to @user
   else
     render 'edit'
   end
 end
 
 def destroy
   User.find(params[:id]).destroy
   flash[:success] = "User deleted"
   redirect_to users_url
 end
 
 def following
   @title = "Following"
   @user  = User.find(params[:id])
   @users = @user.following.paginate(page: params[:page])
   render 'show_follow'
 end
 def followers
   @title = "Followers"
   @user  = User.find(params[:id])
   @users = @user.followers.paginate(page: params[:page])
   render 'show_follow'
 end
 private
   #paramsの中身を:userの:name,:email,:password,:password_confirmationのみにして返す
   #StrongParameterというやつ
   def user_params
     params.require(:user).permit(:name, :email, :password,
                                  :password_confirmation)
   end
   # beforeアクション
   # 正しいユーザーかどうか確認
   def correct_user
     @user = User.find(params[:id])
     redirect_to(root_url) unless current_user?(@user)
   end
   
       # 管理者かどうか確認
   def admin_user
     redirect_to(root_url) unless current_user.admin?
   end
end

リスト19.04
app/helpers/sessions_helper.rb
----------------------------
module SessionsHelper
 # 渡されたユーザーをログイン状態にする
 def log_in(user)
   session[:user_id] = user.id
 end
 # ユーザーのセッションを永続的にする
 def remember(user)
   user.remember
   cookies.permanent.signed[:user_id] = user.id
   cookies.permanent[:remember_token] = user.remember_token
 end
 # 渡されたユーザーがログイン済みユーザーであればtrueを返す
 def current_user?(user)
   user == current_user
 end
 # 現在ログイン中のユーザーを返す (いる場合)
 def current_user
   if (user_id = session[:user_id])
     @current_user ||= User.find_by(id: user_id)
   elsif (user_id = cookies.signed[:user_id])
     user = User.find_by(id: user_id)
     if user && user.authenticated?(:remember, cookies[:remember_token])
       log_in user
       @current_user = user
     end
   end
 end
 
 # ユーザーがログインしていればtrue、その他ならfalseを返す
 def logged_in?
   !current_user.nil?
 end
 
 # 永続的セッションを破棄する
 def forget(user)
   user.forget
   cookies.delete(:user_id)
   cookies.delete(:remember_token)
 end
 # 現在のユーザーをログアウトする
 def log_out
   forget(current_user)
   session.delete(:user_id)
   @current_user = nil
 end
 
 # 記憶したURL (もしくはデフォルト値) にリダイレクト
 # /sample_app/app/controllers/sessions_controller.rb
 # のcreateアクションから呼ばれる
 def redirect_back_or(default)
   redirect_to(session[:forwarding_url] || default)
   session.delete(:forwarding_url)
 end
 # アクセスしようとしたURLを覚えておく
 def store_location
   session[:forwarding_url] = request.original_url if request.get?
 end
end

リスト19.05
app/models/micropost.rb
----------------------------
class Micropost < ApplicationRecord
 #つぶやきは1人のユーザーを持つ
 belongs_to :user
 default_scope -> { order(created_at: :desc) }
 mount_uploader :picture, PictureUploader
 validates :user_id, presence: true
 validates :content, presence: true, length: { maximum: 140 }
 validate  :picture_size
 private
   # アップロードされた画像のサイズをバリデーションする
   def picture_size
     if picture.size > 5.megabytes
       errors.add(:picture, "should be less than 5MB")
     end
   end
end

リスト19.06
app/models/user.rb
----------------------------
class User < ApplicationRecord
 #userはたくさんのmicropostsを持つ
 has_many :microposts, dependent: :destroy
 
 has_many :active_relationships,  class_name:  "Relationship",
                                  foreign_key: "follower_id",
                                  dependent:   :destroy
 has_many :passive_relationships, class_name:  "Relationship",
                                  foreign_key: "followed_id",
                                  dependent:   :destroy
 has_many :following, through: :active_relationships,  source: :followed
 has_many :followers, through: :passive_relationships, source: :follower
 
 #トークンを作成
 #リメンバーミー用トークン
 attr_accessor :remember_token
 #承認用トークン
 attr_accessor :activation_token
 #パスワードリセット用トークン
 attr_accessor :reset_token
 #データベースへ登録前と更新前のどちらかでメールアドレスを小文字にする
 before_save   :downcase_email
 
 #データベースへ登録前にトークンとダイジェストを作成する
 before_create :create_activation_digest
 
 #名前を表す
 #空白NG
 #最大50文字
 validates :name,  presence: true, length: { maximum: 50 }
                     
 #emailを表す
 #正規表現用の文字列をVALID_EMAIL_REGEXへ
 #空白NG
 #最大255文字
 #フォーマットはVALID_EMAIL_REGEXに従う
 #一意であること
 VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
 validates :email, presence: true,
                   length: { maximum: 255 },
                   format: { with: VALID_EMAIL_REGEX },
                   uniqueness: { case_sensitive: false }
 has_secure_password
 validates :password, presence: true, length: { minimum: 6 }, allow_nil: true
 # 渡された文字列のハッシュ値を返す
 def User.digest(string)
   cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
                                                 BCrypt::Engine.cost
   BCrypt::Password.create(string, cost: cost)
 end
 
 # ランダムなトークンを返す
 def User.new_token
   SecureRandom.urlsafe_base64
 end
 
 # 永続セッションのためにユーザーをデータベースに記憶する
 def remember
   self.remember_token = User.new_token
   update_attribute(:remember_digest, User.digest(remember_token))
 end
 
 # トークンがダイジェストと一致したらtrueを返す
 #app/controllers/account_activations_controller.rbのeditアクションで呼ばれる
 def authenticated?(attribute, token)
   #メタプログラミングでactivation_digestインスタンスを取得する
   digest = send("#{attribute}_digest")
   #たぶんないが、念のためnilでないことを確認する
   return false if digest.nil?
   #インスタンスのダイジェストとトークンから生成したダイジェストが
   #一致すればtrue
   #一致しなければfalse
   BCrypt::Password.new(digest).is_password?(token)
 end
 
 # ユーザーのログイン情報を破棄する
 def forget
   update_attribute(:remember_digest, nil)
 end
 
 # アカウントを有効にする
 def activate
   #有効化状態と、有効化日時を更新
   update_columns(activated: true, activated_at: Time.zone.now)
 end
 # 有効化用のメールを送信する
 #app/controllers/users_controller.rbから呼ばれる
 def send_activation_email
   #メイラーを使ってメールを今すぐに送信する
   #account_activationの定義はapp/mailers/user_mailer.rbにある
   UserMailer.account_activation(self).deliver_now
 end
 # パスワード再設定の属性を設定する
 def create_reset_digest
   self.reset_token = User.new_token
   update_columns(reset_digest: User.digest(reset_token), reset_sent_at: Time.zone.now)
 end
 # パスワード再設定のメールを送信する
 def send_password_reset_email
   UserMailer.password_reset(self).deliver_now
 end
 
 # パスワード再設定の期限が切れている場合はtrueを返す
 def password_reset_expired?
   reset_sent_at < 2.hours.ago
 end
 
 # ユーザーのステータスフィードを返す
 def feed
   following_ids = "SELECT followed_id FROM relationships
                    WHERE follower_id = :user_id"
   Micropost.where("user_id IN (#{following_ids})
                    OR user_id = :user_id", user_id: id)
 end
 # ユーザーをフォローする
 def follow(other_user)
   following << other_user
 end
 # ユーザーをフォロー解除する
 def unfollow(other_user)
   active_relationships.find_by(followed_id: other_user.id).destroy
 end
 # 現在のユーザーがフォローしてたらtrueを返す
 def following?(other_user)
   following.include?(other_user)
 end
 
 private
   # メールアドレスをすべて小文字にする
   def downcase_email
     self.email = email.downcase
   end
   # 有効化トークンとダイジェストを作成および代入する
   def create_activation_digest
     #有効化用トークンを作成する
     self.activation_token  = User.new_token
     #トークンを元にダイジェストを作成する
     self.activation_digest = User.digest(activation_token)
   end
end

リスト19.07
app/views/layouts/_header.html.erb
----------------------------
<%# 以下はBootstrapのクラスです
 navbar
 navbar-fixed-top
 navbar-inverse
 container
 nav
 navbar-nav
 navbar-right
%>
<header class="navbar navbar-fixed-top navbar-default">
 <div class="container">
   <%# ロゴ %>
   <%= link_to "魔改造", root_path, id: "logo" %>
   
   <nav>
     <ul class="nav navbar-nav navbar-right">
       <%# 右上に表示するリンク %>
       <li><%= link_to "ホーム", root_path %></li>
       <li><%= link_to "ヘルプ", help_path %></li>
       
       <%# ログインしているとき %>
       <% if logged_in? %>
         <%# ユーザーを探す %>
         <li><%= link_to "ユーザーを探す", users_path %></li>
         
         <%# ドロップダウン形式にする %>
         <li class="dropdown">
           <a href="#" class="dropdown-toggle" data-toggle="dropdown">
             <%# ドロップダウンの名前のところをユーザー名にする %>
             <%= current_user.name %> <b class="caret"></b>
           </a>
           
           
           <%# ドロップダウンの内容について %>
           <ul class="dropdown-menu">
             <%# プロフィール %>
             <li><%= link_to "プロフィール", current_user %></li>
             <%# 設定 %>
             <li><%= link_to "設定", edit_user_path(current_user) %></li>
             <%# 区切り線 %>
             <li class="divider"></li>
             <%# 設定 %>
             <li>
               <%= link_to "ログアウト", logout_path, method: :delete %>
             </li>
           </ul>
         </li>
       <%# ログインしていないとき %>
       <% else %>
         <li><%= link_to "ログイン", login_path %></li>
       <% end %>
     </ul>
   </nav>
 </div>
</header>

リスト19.08
app/views/microposts/_micropost.html.erb
----------------------------
<%# /sample_app/app/views/users/show.html.erbから呼ばれる %>
<li id="micropost-<%= micropost.id %>">
 
 <%# アイコンはユーザーページに飛ぶようにする %>
 <%= link_to gravatar_for(micropost.user, size: 50), micropost.user %>
 <%# ユーザー名もユーザーページに飛ぶようにする %>
 <span class="user"><%= link_to micropost.user.name, micropost.user %></span>
 <%# つぶやき内容を表示し、画像つきであれば画像も表示する %>
 <span class="content">
   <%= micropost.content %>
   <%= image_tag micropost.picture.url if micropost.picture? %>
 </span>
 
 
 <%# 時間を表示する %>
 <span class="timestamp">
   <%# 時間の表示 %>
   <%= time_ago_in_words(micropost.created_at) %>前
   <%# ツイ主なら削除ボタンを表示 %>
   <%# 削除を承認したら、/sample_app/app/controllers/microposts_controller.rbのdestroyが呼ばれる%>
   <% if current_user?(micropost.user) %>
     <%= link_to "ツイートを削除", micropost, method: :delete,
                                      data: { confirm: "本当にいいですか?" } %>
   <% end %>
 </span>
</li>

リスト19.09
app/views/shared/_stats.html.erb
----------------------------
<%# /sample_app/app/views/users/show.html.erbから呼ばれる %>
<% @user ||= current_user %>
<div class="stats">
 <%# フォローの数を表示する %>
 <a href="<%= following_user_path(@user) %>">
   <strong id="following" class="stat">
     <%= @user.following.count %>
   </strong>
   フォロー
 </a>
 <%# フォロワーの数を表示する%>
 <a href="<%= followers_user_path(@user) %>">
   <strong id="followers" class="stat">
     <%= @user.followers.count %>
   </strong>
   フォロワー
 </a>
</div>

リスト19.10
app/views/users/_follow.html.erb
----------------------------
<%# /sample_app/app/views/users/_follow_form.html.erbから呼ばれる %>
<%= form_for(current_user.active_relationships.build, remote: true) do |f| %>
 <div><%= hidden_field_tag :followed_id, @user.id %></div>
 <%= f.submit "フォローする", class: "btn btn-primary" %>
<% end %>

リスト19.11
app/views/users/_follow_form.html.erb
----------------------------
<%# /sample_app/app/views/users/show.html.erbから呼ばれる %>
<%# ログイン中のユーザーでなかったらフォローボタンとか表示する %>
<% unless current_user?(@user) %>
 <div id="follow_form">
 <%# フォロー中ならフォロー中ボタン %>
 <% if current_user.following?(@user) %>
   <%# /sample_app/app/views/users/_unfollow.html.erbへ %>
   <%= render 'unfollow' %>
 <%# フォローしてなければフォローボタン %>
 <% else %>
   <%# /sample_app/app/views/users/_follow.html.erbへ %>
   <%= render 'follow' %>
 <% end %>
 </div>
<% end %>

リスト19.12
app/views/users/_unfollow.html.erb
----------------------------
<%# /sample_app/app/views/users/_follow_form.html.erbから呼ばれる %>
<%= form_for(current_user.active_relationships.find_by(followed_id: @user.id),
            html: { method: :delete },
            remote: true) do |f| %>
 <%= f.submit "フォロー中", class: "btn btn-danger" %>
<% end %>

リスト19.13
app/views/users/show.html.erb
----------------------------
<%#
/sample_app/app/controllers/users_controller.rbのshowから飛ぶ
   #userの情報を取得する
   @user = User.find(params[:id])
   #userの持つmicropostを取得する
   #paginateメソッドとシンボルとparamsは
   @microposts = @user.microposts.paginate(page: params[:page])
%>
<% provide(:title, @user.name) %>
<%# BootStrapで区切る%>
<div class="row">
 
 <%# 左側4つはアイコンと名前とフォロー数とフォロワー数を表示 %>
 <aside class="col-md-4">
   <section class="user_info">
     <h1>
       
       <%# ユーザーアイコン %>
       <%= gravatar_for @user %>
       <%# ユーザー名 %>
       <%= @user.name %>
     </h1>
   </section>
   
   <%#
   フォローとフォロワーの数を表示する
   /sample_app/app/views/shared/_stats.html.erb
   %>
   <section class="stats">
     <%# /sample_app/app/views/shared/_stats.html.erbへ%>
     <%= render 'shared/stats' %>
   </section>
 </aside>
 <%# 右側8つ %>
 <div class="col-md-8">
   <%# フォローボタン %>
   <%#/sample_app/app/views/users/_follow_form.html.erbへ %>
   <%= render 'follow_form' if logged_in? %>
   
   <%# つぶやきを表示する %>
   <% if @user.microposts.any? %>
     <h3>ツイート <%= @user.microposts.count %></h3>
     
     <%# マイクロポスト %>
     <%# /sample_app/app/views/microposts/_micropost.html.erbへ%>
     <ol class="microposts">
       <%= render @microposts %>
     </ol>
     <%= will_paginate @microposts %>
   <% end %>
 </div>
</div>

リスト19.14
config/routes.rb
----------------------------
Rails.application.routes.draw do
 
 # ルートページ
 root   'static_pages#home'
 
 get    '/help',    to: 'static_pages#help'
 get    '/about',   to: 'static_pages#about'
 get    '/contact', to: 'static_pages#contact'
 
 # 新規登録ページは、/signup
 # app/controllers/users_controller.rbのnewアクションへ
 get    '/signup',  to: 'users#new'
 
 #ログイン画面へのルーティング
 #/sample_app/app/controllers/sessions_controller.rbへ
 get    '/login',   to: 'sessions#new'
 #ログイン画面
 #/sample_app/app/controllers/sessions_controller.rbへ
 post   '/login',   to: 'sessions#create'
 delete '/logout',  to: 'sessions#destroy'
 
 #ユーザーのルーティングを自動で作成する
 resources :users do
   member do
     get :following, :followers
   end
 end
 #アカウント有効化用ルーティングをeditのみ作成する
 #edit_account_activation_urlで、以下が実行される
 #app/controllers/users_controller.rbのeditアクション
 resources :account_activations, only: [:edit]
 
 
 resources :password_resets,     only: [:new, :create, :edit, :update]
 resources :microposts,          only: [:create, :destroy]
 resources :relationships,       only: [:create, :destroy]
end

リスト19.15
test/integration/microposts_interface_test.rb
----------------------------
require 'test_helper'
class MicropostsInterfaceTest < ActionDispatch::IntegrationTest
 def setup
   @user = users(:michael)
 end
 
 test "micropost interface" do
   log_in_as(@user)
   get root_path
   assert_select 'div.pagination'
   assert_select 'input[type="file"]'
   # 無効な送信
   post microposts_path, params: { micropost: { content: "" } }
   assert_select 'div#error_explanation'
   # 有効な送信
   content = "This micropost really ties the room together"
   picture = fixture_file_upload('test/fixtures/rails.png', 'image/png')
   assert_difference 'Micropost.count', 1 do
     post microposts_path, params: { micropost:
                                     { content: content,
                                       picture: picture } }
   end
   assert assigns(:micropost).picture?
   follow_redirect!
   assert_match content, response.body
   # 投稿を削除する
#    assert_select 'a', 'delete'
   first_micropost = @user.microposts.paginate(page: 1).first
   assert_difference 'Micropost.count', -1 do
     delete micropost_path(first_micropost)
   end
   # 違うユーザーのプロフィールにアクセスする
   get user_path(users(:archer))
   assert_select 'a', { text: 'delete', count: 0 }
 end
 test "micropost sidebar count" do
   log_in_as(@user)
   get root_path
   assert_match "#{@user.microposts.count} microposts", response.body
   # まだマイクロポストを投稿していないユーザー
   other_user = users(:malory)
   log_in_as(other_user)
   get root_path
   assert_match "0 microposts", response.body
   other_user.microposts.create!(content: "A micropost")
   get root_path
   assert_match "1 micropost", response.body
 end
end


19.10.2 本章のまとめ

なぜusers/1でプロフィール画面が表示されるのかイマイチわかっていなかったが、しっかりと把握することができた。
users/1で、users_controllerのshowアクションが呼ばれることがわかった。
それは、config/routes.rbのresources :usersのおかげであることがわかった。
will_paginateがどの部分を担当しているのか把握することができた。
daysやhourというのは、gemで日本語化できそうというのがわかった。
マイクロソフト削除時、どのメソッドが担当しているのかわかった。
また、削除後のURLをどうしているか、どこが担当しているのかもわかった。

修正前

スクリーンショット 2020-01-20 02.56.06

スクリーンショット 2020-01-20 02.56.44


スクリーンショット 2020-01-20 02.56.13

スクリーンショット 2020-01-20 02.56.19


修正後

スクリーンショット 2020-01-20 02.55.46

スクリーンショット 2020-01-20 02.56.36

スクリーンショット 2020-01-20 02.55.53

スクリーンショット 2020-01-20 02.56.00


この記事が気に入ったらサポートをしてみませんか?