0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Rails チュートリアル 第10章 備忘録

Posted at

第10章の備忘録です。

##目次
1 新しいタブでリンクを開く方法
2 PATCHリクエストの送り方
3 テストreloadする必要性
4 パスワードの例外処理
5 認証と認可の違い
6 フレンドリーフォワーディング
7 Faker gem
8 ページネーション
9 確認ログの出し方

##1 新しいタブでリンクを開く方法
クリック先のページを新しいタブで開きたい時は、target属性を下のコードのように追加する。
またtarget="_blank"だけだとフィッシングサイトなどを導入される恐れがあるので、rel="noopener"属性を下のコードのように追加する必要がある。

app/views/users/edit.html.erb
    .
    .
    <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を内部で判定し、そこでPOSTPATCHを自動で判定している。

##3 テストreloadする必要性
この章のテストコードで、新しくreloadメソッドが出てきた。
使用箇所は、下のコードなどが挙げられる。
このメソッドを差し込むことで、ページを更新した後に、assert_equal``assert_selectメソッドを使って、ページの更新前後で変更されているかなどのチェックができる。

test/integration/users_edit_test.rb
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オプションを使用する。

app/models/user.rb
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を用いて管理する。

app/helpers/sessions_helper.rb
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
サンプルユーザーを作成したい時はFakergemを使うと簡単に作成することができる。

通常は開発環境のみだが、今回は全ての環境で使用する。

Gemfile
.
gem 'rails', '6.0.3'
gem 'bcrypt', '3.1.13'
gem 'faker', '2.1.2'
.
$ bundle install
db/seeds.rb
# メインのサンプルユーザーを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_paginategem
bootstrap-will_paginategem を使う。

Gemfile
.
gem 'faker', '2.1.2'
gem 'will_paginate', '3.1.8'
gem 'bootstrap-will_paginate', '1.0.0'
.
.
$ bundle install

表示したい位置に<%= will_paginate %>を記述

app/views/users/index.html.erb
<% 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)

app/controllers/users_controller.rb
 .
  def index
    @users = User.paginate(page: params[:page])
  end
  .
  .

##9 確認ログの出し方
何かデータを削除する時、ボタンを1度押しただけで実行されてしまう状態だと、押し間違いで削除してしまう恐れがある。
そのために、削除ボタンを押したら確認ログのようなものを出すことで防ぐことができる。
その設定はすごく簡単で、data: { confirm: "表示したい文字列" }を加えるだけで可能!!

<%= link_to "delete", user, method: :delete,
            data: { confirm: "You suer?" }
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?