3
2

More than 3 years have passed since last update.

【Rails】ユーザー一覧の表示とページネーション【Rails Tutorial 10章まとめ】

Posted at

ユーザー一覧ページ

indexアクションの認可

ユーザー一覧を表示するindexアクションとビューはログインユーザーにのみ表示したいので、logged_in_userを設定する。

app/controllers/users_controller.rb
class UsersController < ApplicationController
  before_action :logged_in_user, only: [:index, :edit, :update]
  before_action :correct_user,   only: [:edit, :update]

  def index
    @users = User.all
  end
  .
  .
  .
end

indexアクションには@users変数に全てのUserオブジェクトを入れておく。

テストを書く。

test/controllers/users_controller_test.rb
  test "should redirect index when not logged in" do
    get users_path
    assert_redirected_to login_url
  end

indexビュー

ユーザー一覧ページ用のindexビューを作成する。

app/views/users/index.html.erb
<% provide(:title, 'All users') %>
<h1>All users</h1>

<ul class="users">
  <% @users.each do |user| %>
    <li>
      <%= gravatar_for user, size: 50 %>
      <%= link_to user.name, user %>
    </li>
  <% end %>
</ul>

ヘッダーにユーザー一覧ページへのリンクを貼っておく。

app/views/layouts/_header.html.erb
 <% if logged_in? %>
          <li><%= link_to "Users", users_path %></li>
          <li class="dropdown">
  .
  .
  .

サンプルユーザーの生成

ユーザー一覧に表示するサンプルユーザーを手作業で作っていると手間なので、fakerジェムを使ってユーザーを大量生成する。

Gemfileにfakerジェムを追加する。

Gemfile
gem 'faker', '1.7.3'

seedファイルにユーザーを生成するRailsスクリプト(Railsタスク)を書く。

db/seeds.rb
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!メソッドはcreateメソッドと違い、ユーザーが無効な場合でも例外を返すため、余計なエラーの現にならずに済む。

データベースのリセットと、Railsタスクの実行を行う。

rails db:migrate:reset
rails db:seed

エラーを吐く場合はローカルサーバーを止めたりしてみる。
(自分の場合はseedファイルにデフォルトで入っていたコメントを残していたらエラーを吐いた。)

ページネーション

will_paginateメソッド

一つのページに表示するユーザーを30人までとして、それ以降はページを切り替えて表示するページネーションを実装する。
まずGemfileにwill_paginateジェムとbootstrap-will_paginateジェムを追加する。

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

ページネーションを実装するには、まずindexビューのユーザー表示部分を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アクションの@users = User.allをUser.paginate(page: params[:page])に変える。

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

paginateメソッドは、:pageパラメータが1であれば1−30のユーザーを、2であれば31−60のユーザーを取り出す(30人ずつ取り出す設定にしている場合)。

ここでエラーを吐く場合は、will_paginateジェムのバージョンを上げてみるとよい。

ユーザー一覧ページのテスト

テスト用ユーザーの生成

fixtureファイルに、テスト用ユーザーを大量生成するRailsタスクを書く。

test/fixtures/users.yml
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') %>

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

テスト

ユーザー一覧ページ用の統合テストを作成する。

$ rails generate integration_test users_index

paginationクラスを持ったdivタグをチェックして、最初のページにユーザーがいることを確認する。

test/integration/users_index_test.rb
require 'test_helper'

class UsersIndexTest < ActionDispatch::IntegrationTest

  def setup
    @user = users(:michael)
  end

  test "index including pagination" do
    log_in_as(@user)
    get users_path
    assert_template 'users/index'
    assert_select 'div.pagination'
    User.paginate(page: 1).each do |user|
      assert_select 'a[href=?]', user_path(user), text: user.name
    end
  end
end

テストでは1ページ目に表示されるユーザーの名前が、各ユーザーのプロフィールページにリンクしていることを確認している。

ユーザー一覧ページのパーシャル

割愛する。

3
2
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
3
2