railsチュートリアル魔改造編 第18章 ログイン画面魔改造
第18章 ログイン画面改造編
ログイン画面を魔改造していきます。
いつものようにトピックブランチを作成します。
cd ~/environment/sample_app
git checkout -b rails-makaizou-18
18.1 ログイン画面はどこから飛ぶ?
基本的に、ヘッダーのログイン画面をクリックすると飛ぶ。
URLは/login
またはlogin_path
/sample_app/config/routes.rb
で、
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
がそれに該当する行
getは、入った時に実行されるイメージ
postは、ログイン画面でログインボタンが押された時に実行されるイメージ
18.2 ログイン画面の文字列を魔改造
/loginのビューは
/sample_app/app/views/sessions/new.html.erb
の通り
ここを書き弄っていく
文字列は、
f.label :hoge
となっていた部分を
f.label :hoge, "ホゲ"
みたいな感じで変更していくと書き換わる
ただし!チェックボックスの場合は注意!
表示文字列はspanで指定しているので同じようなノリで書き換えるとハマる。
※ハマった
18.3 ログイン画面のエラー文を魔改造
エラー文は、新規登録画面と異なり、全てオリジナルの文章なので変更しやすい。
form_forの仕様で、:sessionを使用しているので、sessionsコントローラのcreateを呼ぶようになっている。
/sample_app/app/controllers/sessions_controller.rb
ユーザーが有効化されていないときの警告文を変更する。
また、ルートページに飛ぶとユーザビリティが落ちると思ったので、ログイン画面を再表示するようにする。
このとき、flashに文字を入れているが、再表示なのでflash.nowに変更する必要がある。
ユーザーが存在していない場合のエラー文も変更する。
/sample_app/app/views/layouts/application.html.erb
ログインしたときになにもメッセージがないと寂しいので、ログインしたらおかえりなさいって表示するとまたログインしたくなるような気がする
ここまでで、rails testが失敗するはずである。
ログ
----------------------------
ec2-user:~/environment/sample_app (rails-makaizou-18) $ rails test
Running via Spring preloader in process 7992
Started with run options --seed 21867
FAIL["test_should_redirect_update_when_logged_in_as_wrong_user", UsersControllerTest, 1.9434154359996683]
test_should_redirect_update_when_logged_in_as_wrong_user#UsersControllerTest (1.94s)
Expected false to be truthy.
test/controllers/users_controller_test.rb:53:in `block in <class:UsersControllerTest>'
FAIL["test_should_redirect_edit_when_logged_in_as_wrong_user", UsersControllerTest, 2.026156476000324]
test_should_redirect_edit_when_logged_in_as_wrong_user#UsersControllerTest (2.03s)
Expected false to be truthy.
test/controllers/users_controller_test.rb:45:in `block in <class:UsersControllerTest>'
74/74: [=================================] 100% Time: 00:00:02, Time: 00:00:02
Finished in 2.81768s
74 tests, 421 assertions, 2 failures, 0 errors, 0 skips
----------------------------
いずれの理由も、ログイン時に文字を表示するように変更したことで、テストに失敗するようになったこと。
ここは仕様変更で書き換わる可能性があるので、該当のテストコードはコメントアウトにする。
18.4 最後に
保存する
rails test
git add -A
git status
ログ
----------------------------
ec2-user:~/environment/sample_app (rails-makaizou-18) $ git status
On branch rails-makaizou-18
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: app/controllers/account_activations_controller.rb
modified: app/controllers/sessions_controller.rb
modified: app/views/sessions/new.html.erb
modified: app/views/users/new.html.erb
modified: config/routes.rb
modified: test/controllers/users_controller_test.rb
----------------------------
6ファイル修正したことを確認
git commit -m "add 18"
git checkout master
修正前ファイルをブログ用に保存しておく
git merge rails-makaizou-18
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/
18.4.1 修正後
リスト18.01
app/controllers/account_activations_controller.rb
----------------------------
class AccountActivationsController < ApplicationController
#メールアドレスからURLを辿ったあとに呼び出される
def edit
#メールアドレスを元に、テーブルから1件だけユーザー情報を取得する
#params[:email]とparams[:id]は、本文のerb(viewのなんとかmailer)で作成される
user = User.find_by(email: params[:email])
#ユーザーが存在しており、有効化はまだ済んでおらず、ダイジェストとトークンが一致するとき
#activatedはdb/migrate/〇〇_add_activation_to_users.rbに定義がある
#authenticated?は/sample_app/app/models/user.rbに定義がある
if user && !user.activated? && user.authenticated?(:activation, params[:id])
#ユーザーを有効化する
#app/models/user.rbに定義がある
user.activate
#ユーザーをログイン状態にする
#app/helpers/sessions_helper.rbに定義がある
log_in user
#有効化に成功したときのメッセージを出力する
flash[:success] = user.name+"さん、railsチュートリアル魔改造へようこそ!"
#ユーザーページへ
redirect_to user
#認証になんらかの理由で失敗したとき
else
#有効化に失敗したときのメッセージを出力する
flash[:danger] = "申し訳ありません。認証に失敗しました。パスワードの変更をお願いします。"
#トップページへ
redirect_to root_url
end
end
end
----------------------------
リスト18.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 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
----------------------------
リスト18.03
app/views/sessions/new.html.erb
----------------------------
<%#
ここに表示されるエラー文は
/sample_app/app/views/layouts/application.html.erb
で表示される
%>
<%#タブにログインと表示する %>
<% provide(:title, "ログイン") %>
<h1>ログイン</h1>
<%#BootStrap適用 %>
<div class="row">
<%# 3-6-3の割合で配置 %>
<div class="col-md-6 col-md-offset-3">
<%# フォーム %>
<%= form_for(:session, url: login_path) do |f| %>
<%= f.label :email, "メールアドレス" %>
<%= f.email_field :email, class: 'form-control' %>
<%= f.label :password, "パスワード" %>
<%= link_to "(パスワードを忘れた場合はこちら)", new_password_reset_path %>
<%= f.password_field :password, class: 'form-control' %>
<%#
do~endで括られた部分をラベルにしており、チェックボックスが含まれている
ため本文を分けている
%>
<%= f.label :remember_me, class: "checkbox inline" do %>
<%= f.check_box :remember_me %>
<span>ブラウザを閉じてもログイン状態を維持する</span>
<% end %>
<%# form_forで:sessionを指定しているので/sample_app/app/controllers/sessions_controller.rbのcreateを呼ぶ %>
<%= f.submit "ログイン", class: "btn btn-danger" %>
<% end %>
<br>
<p><%= link_to "新規会員登録はこちら!", signup_path %></p>
</div>
</div>
----------------------------
リスト18.04
app/views/users/new.html.erb
----------------------------
<%#
# /signup で呼ばれるアクション
# app/views/users/new.html.erbへ
def new
#ユーザーを新規に作成する
@user = User.new
end
%>
<%# 見出しを新規登録にする %>
<% provide(:title, '新規登録') %>
<%# 見出しを新規登録にする %>
<h1>新規登録</h1>
<%# Bootstrapの機能で、12列に何を割り当てるか決める %>
<div class="row">
<%# 空白3-入力スペース6-空白3の構成にする %>
<div class="col-md-6 col-md-offset-3">
<%# フォームを作成し、@userにデータを入れていく %>
<%= form_for(@user) do |f| %>
<%# エラー文を出力する %>
<%= render 'shared/error_messages', object: f.object %>
<%# 名前 %>
<%= f.label :name, "名前" %>
<%= f.text_field :name, class: 'form-control' %>
<%# メールアドレス %>
<%= f.label :email, "メールアドレス" %>
<%= f.email_field :email, class: 'form-control' %>
<%# パスワード %>
<%= f.label :password, "パスワード" %>
<%= f.password_field :password, class: 'form-control' %>
<%# パスワード(再入力) %>
<%= f.label :password_confirmation, "パスワード(再入力)" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%# パスワード(再入力) %>
<%# form_forで:userを指定しているので/sample_app/app/controllers/users_controller.rbのcreateを呼ぶ %>
<%= f.submit "魔改造アカウントを作成する", class: "btn btn-danger" %>
<% end %>
</div>
</div>
----------------------------
リスト18.05
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
----------------------------
リスト18.06
test/controllers/users_controller_test.rb
----------------------------
require 'test_helper'
class UsersControllerTest < ActionDispatch::IntegrationTest
def setup
@user = users(:michael)
@other_user = users(:archer)
end
test "should redirect index when not logged in" do
get users_path
assert_redirected_to login_url
end
test "should get new" do
get signup_path
assert_response :success
end
test "should redirect edit when not logged in" do
get edit_user_path(@user)
assert_not flash.empty?
assert_redirected_to login_url
end
test "should redirect update when not logged in" do
patch user_path(@user), params: { user: { name: @user.name,
email: @user.email } }
assert_not flash.empty?
assert_redirected_to login_url
end
test "should not allow the admin attribute to be edited via the web" do
log_in_as(@other_user)
assert_not @other_user.admin?
patch user_path(@other_user), params: {
user: { password: @other_user.password,
password_confirmation: @other_user.password,
admin: true } }
assert_not @other_user.reload.admin?
end
test "should redirect edit when logged in as wrong user" do
log_in_as(@other_user)
get edit_user_path(@user)
# assert flash.empty?
assert_redirected_to root_url
end
test "should redirect update when logged in as wrong user" do
log_in_as(@other_user)
patch user_path(@user), params: { user: { name: @user.name,
email: @user.email } }
# assert flash.empty?
assert_redirected_to root_url
end
test "should redirect destroy when not logged in" do
assert_no_difference 'User.count' do
delete user_path(@user)
end
assert_redirected_to login_url
end
test "should redirect destroy when logged in as a non-admin" do
log_in_as(@other_user)
assert_no_difference 'User.count' do
delete user_path(@user)
end
assert_redirected_to root_url
end
test "should redirect following when not logged in" do
get following_user_path(@user)
assert_redirected_to login_url
end
test "should redirect followers when not logged in" do
get followers_user_path(@user)
assert_redirected_to login_url
end
end
----------------------------
18.4.2 本章のまとめ
チェックボックスの右に表示されている文字列は、他の入力フォームと異なり、シンボルの横に文字列を入れて表示文字列を変更できないので注意。
どの入力フォームも、newビューから送信ボタンを押すとcreateアクションに飛ぶ
新規登録時のflashの文字の表示方法と、ログイン時のflashの文字の表示方法は異なる。
有効化してない時にログインしてトップページに戻されるのはどうなんだろう?ということで再表示するようにした。
修正前
修正後
この記事が気に入ったらサポートをしてみませんか?