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をどうしているか、どこが担当しているのかもわかった。
修正前
修正後
この記事が気に入ったらサポートをしてみませんか?