ユーザー一覧ページ
indexアクションの認可
ユーザー一覧を表示するindexアクションとビューはログインユーザーにのみ表示したいので、logged_in_userを設定する。
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 "should redirect index when not logged in" do
get users_path
assert_redirected_to login_url
end
indexビュー
ユーザー一覧ページ用のindexビューを作成する。
<% 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>
ヘッダーにユーザー一覧ページへのリンクを貼っておく。
<% if logged_in? %>
<li><%= link_to "Users", users_path %></li>
<li class="dropdown">
.
.
.
サンプルユーザーの生成
ユーザー一覧に表示するサンプルユーザーを手作業で作っていると手間なので、fakerジェムを使ってユーザーを大量生成する。
Gemfileにfakerジェムを追加する。
gem 'faker', '1.7.3'
seedファイルにユーザーを生成するRailsスクリプト(Railsタスク)を書く。
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ジェムを追加する。
gem 'will_paginate', '3.1.6'
gem 'bootstrap-will_paginate', '1.0.0'
ページネーションを実装するには、まずindexビューのユーザー表示部分を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アクションの@users = User.allをUser.paginate(page: params[:page])に変える。
def index
@users = User.paginate(page: params[:page])
end
paginateメソッドは、:pageパラメータが1であれば1−30のユーザーを、2であれば31−60のユーザーを取り出す(30人ずつ取り出す設定にしている場合)。
ここでエラーを吐く場合は、will_paginateジェムのバージョンを上げてみるとよい。
ユーザー一覧ページのテスト
テスト用ユーザーの生成
fixtureファイルに、テスト用ユーザーを大量生成するRailsタスクを書く。
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タグをチェックして、最初のページにユーザーがいることを確認する。
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ページ目に表示されるユーザーの名前が、各ユーザーのプロフィールページにリンクしていることを確認している。
ユーザー一覧ページのパーシャル
割愛する。