第10章の備忘録です。
##目次
1 新しいタブでリンクを開く方法
2 PATCHリクエストの送り方
3 テストreloadする必要性
4 パスワードの例外処理
5 認証と認可の違い
6 フレンドリーフォワーディング
7 Faker gem
8 ページネーション
9 確認ログの出し方
##1 新しいタブでリンクを開く方法
クリック先のページを新しいタブで開きたい時は、target属性を下のコードのように追加する。
またtarget="_blank"
だけだとフィッシングサイトなどを導入される恐れがあるので、rel="noopener"
属性を下のコードのように追加する必要がある。
.
.
<div class="gravatar_edit">
<%= gravatar_for @user %>
<a href="https://gravatar.com/emails" target="_blank" rel="noopener">change</a>
</div>
</div>
</div>
##2 PATCHリクエストの送り方
new
の時と同様にedit
でフォームヘルパーを使ってコードを書くと、HTMLソースで見てみるとnew
の時と違う箇所がある。
<form accept-charset="UTF-8" action="/users/1" class="edit_user"
id="edit_user_1" method="post">
<input name="_method" type="hidden" value="patch" />
.
.
.
</form>
まず、WebブラウザそのままではPATCH
リクエストを送信することができないため、type="hidden"
でフォームを隠し、そこでPATCH
を設定している。
また、new
の時とform_with(@user)
が全く同じにも関わらず、edit
時ではPATCH
リクエストを送信するように自動で設定される理由は、Railsはユーザーが新規なのか、データベースに存在する既存のユーザーであるかを、new_record?
論理値メソッドで区別してくれるからである。
新規の時はtrue
既存の時はfalse
を内部で判定し、そこでPOST
かPATCH
を自動で判定している。
##3 テストreloadする必要性
この章のテストコードで、新しくreload
メソッドが出てきた。
使用箇所は、下のコードなどが挙げられる。
このメソッドを差し込むことで、ページを更新した後に、assert_equal``assert_select
メソッドを使って、ページの更新前後で変更されているかなどのチェックができる。
require 'test_helper'
.
.
test "successful edit" do
get edit_user_path(@user)
assert_template 'users/edit'
name = "Foo Bar"
email = "foo@bar.com"
patch user_path(@user), params: { user: { name: name,
email: email,
password: "",
password_confirmation: "" } }
assert_not flash.empty?
assert_redirected_to @user
@user.reload # ページを更新
assert_equal name, @user.name
assert_equal email, @user.email
end
end
##4 パスワードの例外処理
名前や画像だけを編集したい時、現状だとパスワードは変更せずとも入力しないと、バリデーションでエラーが起きる。
新規登録時は空のパスワードをバリデーションし、編集時はパスワードを入力せず正常に動作させるためには、allow_nil: true
オプションを使用する。
class User < ApplicationRecord
.
.
has_secure_password
validates :password, presence: true, length: { minimum: 6 }, allow_nil: true
.
end
こうすることで、passwordがnil
になることを許容することができる。
また、has_secure_passwordではオブジェクト生成時だけ存在性を検証するようになっているため、新規作成時は空を許さず、編集時は再度パスワードを入力する必要性をなくすことが可能となる。
##5 認証と認可の違い
- 認証
サイトのユーザーを識別すること。 - 認可
そのユーザーが実行可能な操作を管理すること。
今回では、current_user
のみ編集等ができるように管理
##6 フレンドリーフォワーディング
仮に、ログインしていないユーザーが編集ページにアクセスしようとすると、ログインページへ飛ばされる。ログイン後に変種ページでリダイレクトしてあげたら親切である。
このようなユーザーが閲覧しようとしていたページにしてあげることをフレンドリーフォワーディングという。
実装する時は、開こうとしていたページをsessionを用いて管理する。
module SessionsHelper
.
.
# 記憶したURL(もしくはデフォルト値)にリダイレクト
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
##7 Faker gem
サンプルユーザーを作成したい時はFaker
gemを使うと簡単に作成することができる。
通常は開発環境のみだが、今回は全ての環境で使用する。
.
gem 'rails', '6.0.3'
gem 'bcrypt', '3.1.13'
gem 'faker', '2.1.2'
.
$ bundle install
# メインのサンプルユーザーを1人
User.create!(name: "Example User",
email: "example@railstutorial.org",
password: "foobar",
password_confirmation: "foobar")
# 追加のユーザー
99.times do |n|
name = Faker::Name.name
email = "example-#{n+1}@railstutorial.org"
password = "password"
User.create!(name: name,
email: email,
password: password,
password_confirmation: password)
end
また、create!
メソッドにすることで、失敗した時にfalseではなく、例外を発生してくれるためエラーを見過ごさない
$ rails db:migrate:reset
$ rails db:seed
##8 ページネーション
ページネーションを使用したい時は、
will_paginate
gem
bootstrap-will_paginate
gem を使う。
.
gem 'faker', '2.1.2'
gem 'will_paginate', '3.1.8'
gem 'bootstrap-will_paginate', '1.0.0'
.
.
$ bundle install
表示したい位置に<%= will_paginate %>
を記述
<% provide(:title, 'All users') %>
<h1>All users</h1>
<%= will_paginate %>
<ul class="users">
<% @users.each do |user| %>
<li>
<%= gravatar_for user, size: 50 %>
<%= link_to user.name, user %>
</li>
<% end %>
</ul>
<%= will_paginate %>
最後にindex
アクション時の@user = User.all
を変更して、ページネーションを追加する。
また、:page
パラメーターには初期値は1が入り、最初のページを返す。(デフォルトでは1pageに30)
.
def index
@users = User.paginate(page: params[:page])
end
.
.
##9 確認ログの出し方
何かデータを削除する時、ボタンを1度押しただけで実行されてしまう状態だと、押し間違いで削除してしまう恐れがある。
そのために、削除ボタンを押したら確認ログのようなものを出すことで防ぐことができる。
その設定はすごく簡単で、data: { confirm: "表示したい文字列" }
を加えるだけで可能!!
<%= link_to "delete", user, method: :delete,
data: { confirm: "You suer?" }