kouの技術的メモ

学習した内容の定着やアウトプット用に開設しました

成果物の作成2作品目⑦ 予定管理サービス ユーザー一覧のページネーション機能追加、それに対するテスト。

今回は登録ユーザー数が増えても大丈夫なようにユーザー一覧のページネーション機能追加、

それから、好き勝手にアクセス出来ないように、コントローラのbeforeアクションの追加を行っていこうと思います。

ページネーション

まずgemの追加とbundeleインストール

gem 'will_paginate',           '3.1.6'
gem 'bootstrap-will_paginate', '1.0.0'

コントローラの対応アクションに以下を追加します。今回は5人の表示にします

  def index    
    @users = User.paginate(page: params[:page], per_page: 5)
  end

それからviewのページネイトさせたい範囲をユーザー一覧にwillpaginateで囲みます この際、ページを前後するリンクボタンに表示させる文字もオプションで付けれます。

<%= will_paginate, :previous_label => ' &lt 前へ', :next_label => '次へ &gt' %> %>

<ul class="users">
  <%= render @users %>
</ul>

<%= will_paginate, :previous_label => ' &lt 前へ', :next_label => '次へ &gt' %> %>
仮想ユーザーの追加

実際にページネーションがうまく機能しているか確認するために、仮想のユーザーデータを作ります。

gem 'faker',          '1.7.3'

seedsに以下の記述をします

db/seeds.rb

User.create!(      provider: "twitter",
                   uid:1,
                   user_name: "Example"
                   )

7.times do |n|
  name  = Faker::Name.name
  User.create!(   provider: "twitter",
                  uid:n+1,
                  user_name: name)
end

今回は1ページに付き5人表示なので、とりあえず8人分揃えてみました。

表示は大丈夫だったので、次はテストを書きます。

michael:
  name: Michael Example
  email: michael@example.com
  password_digest: <%= User.digest('password') %>

archer:
  name: Sterling Archer
  email: duchess@example.gov
  password_digest: <%= User.digest('password') %>

lana:
  name: Lana Kane
  email: hands@example.gov
  password_digest: <%= User.digest('password') %>

malory:
  name: Malory Archer
  email: boss@example.gov
  password_digest: <%= User.digest('password') %>

<% 5.times do |n| %>
user_<%= n %>:
  name:  <%= "User #{n}" %>
  email: <%= "user-#{n}@example.com" %>
  password_digest: <%= User.digest('password') %>
<% end %>

続きまして、テストを書きます。

rails g integration_test users_index

フィクスチャー test/fixtures/users.yml

user:
  id: 1
  provider: twitter
  uid:  1
  user_name:  user

otheruser:
  id: 2
  provider: twitter
  uid: 2
  user_name:  other_user
  
<% 7.times do |n| %>
user_<%= n %>:
  id: <%= n + 3 %>
  provider: twitter
  uid:  <%= n + 3 %>
  user_name:  <%= "User #{n}" %>
<% end %>

test/integration/users_index_test.rb

require 'test_helper'

class UsersIndexTest < ActionDispatch::IntegrationTest

  def setup
    @user = users(:user)
  end

  test "ページネーションがうまく機能しているか" do
    get users_path
    assert_template 'users/index'
    assert_select 'div.pagination'
    User.paginate(page: 1, per_page: 5).each do |user|
      assert_select 'a[href=?]', user_path(user), text: user.user_name
    end
  end
end

無事にテストも通過し、実動作もちゃんとしているようなので完成です!