railsチュートリアル第10章 ユーザーの一覧ページ

##すべてのユーザーを表示する
indexアクションを追加しましょう。
すべてのユーザーを一覧表示します。
・データベースにサンプルデータを追加する方法
・将来ユーザー数が膨大になってもindexページを問題なく表示

ページネーション（pagination=ページ分割）の方法を学びます
・ユーザーの一覧
・ページネーション用リンク
・移動用の［Users］リンクのモックアップ

管理者権限を新たに実装し、ユーザーの一覧ページから（管理者であれば）ユーザーを削除できる機能も実装
###ユーザーの一覧ページ
indexアクションを追加しましょう。
不正から守るためにテストを作成
####indexアクションのリダイレクトをテストする
test/controllers/users_controller_test.rb

```rb
require 'test_helper'

class UsersControllerTest < ActionDispatch::IntegrationTest
  def setup
    @user = users(:michael)
    @other_user = users(:archer)
    # テストユーザー
  end
  
  test "should get new" do
    get signup_path
    assert_response :success
  end

  test "should redirect index when not logged in" do
  # indexアクションが正しくリダイレクトするか検証する
    get users_path
    # URLで指定したファイルの送信を要求
    assert_redirected_to login_url
    # login_urlに転送しているか？
  end
.
.
.
end
```
####indexアクションにはログインを要求する 
app/controllers/users_controller.rb

```rb
class UsersController < ApplicationController
  before_action :logged_in_user, only: [:index, :edit, :update]
  before_action :correct_user,   only: [:edit, :update]
  # before_actionメソッドを使って何らかの処理が実行される直前に
  # 特定のメソッドを実行する仕組み
  # ログインをさせる
  # :editと:updateアクションだけ
  
  def index
  end
.
.
.
end
```
:indexを追加する
####ユーザーのindexアクション
app/controllers/users_controller.rb

```rb
class UsersController < ApplicationController
  before_action :logged_in_user, only: [:index, :edit, :update]
  before_action :correct_user,   only: [:edit, :update]
  # before_actionメソッドを使って何らかの処理が実行される直前に
  # 特定のメソッドを実行する仕組み
  # ログインをさせる
  # :editと:updateアクションだけ
  
  def index
    @user = User.all
  end
.
.
.
end
```
下からビューの設定
####ユーザーのindexビュー
app/views/users/index.html.erb

```html
<% 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>
```

####gravatar_forヘルパーにオプション引数を追加する
app/helpers/users_helper.rb

```rb
module UsersHelper

  # 渡されたユーザーのGravatar画像を返す
  def gravatar_for(user, options = { size: 80 })
    size         = options[:size]
    gravatar_id  = Digest::MD5::hexdigest(user.email.downcase)
    gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{size}"
    image_tag(gravatar_url, alt: user.name, class: "gravatar")
  end
end
```

####ユーザーのindexページ用のCSS
app/assets/stylesheets/custom.scss

```scss
/* Users index */

.users {
  list-style: none;
  margin: 0;
  li {
    overflow: auto;
    padding: 10px 0;
    border-bottom: 1px solid $gray-lighter;
  }
}
```
####ユーザー一覧ページへのリンクを更新する
app/views/layouts/_header.html.erb

```rb
<header class="navbar navbar-fixed-top navbar-inverse">
  <div class="container">
    <%= link_to "sample app", root_path, id: "logo" %>
    <nav>
      <ul class="nav navbar-nav navbar-right">
        <li><%= link_to "Home", root_path %></li>
        <li><%= link_to "Help", help_path %></li>
        <% if logged_in? %>
          <li><%= link_to "Users", users_path %></li> 
          <li class="dropdown">
            <a href="#" class="dropdown-toggle" data-toggle="dropdown">
              Account <b class="caret"></b>
            </a>
            <ul class="dropdown-menu">
              <li><%= link_to "Profile", current_user %></li>
              <li><%= link_to "Settings", edit_user_path(current_user) %></li>
              <li class="divider"></li>
              <li>
                <%= link_to "Log out", logout_path, method: :delete %>
              </li>
            </ul>
          </li>
        <% else %>
          <li><%= link_to "Log in", login_path %></li>
        <% end %>
      </ul>
    </nav>
  </div>
</header>
```
#####テスト
```
ubuntu:~/environment/sample_app (updating-users) $ rails tRunning via Spring preloader in process 12918
Started with run options --seed 502

  37/37: [============================] 100% Time: 00:00:07, Time: 00:00:07

Finished in 7.13678s
37 tests, 94 assertions, 0 failures, 0 errors, 0 skips
```

###演習
1.
レイアウトにあるすべてのリンクに対して統合テストを書いてみましょう。ログイン済みユーザーとそうでないユーザーのそれぞれに対して、正しい振る舞いを考えてください。ヒント: log_in_asヘルパーを使ってリスト 5.32にテストを追加してみましょう。

「books」コントロールに含まれるアクションに対するレイアウトを設定する場合には、「app/views/layouts/books.html.erb」を作成しておくと自動的に適用されます。
```test/integration/site_layout_test.rb```　
統合テストに含まれているレイアウトを設定するためこのファイルに書く

答え

```rb
require 'test_helper'

class SiteLayoutTest < ActionDispatch::IntegrationTest
.
.
.
  def setup
    @user       = users(:michael)
  end
  
  test "layout links when logged in" do
    log_in_as(@user)
    # ログインする
    get root_path
    # ホーム画面にいく
    assert_template 'static_pages/home'
    # ホーム画面に着いているか？
    assert_select "a[href=?]", users_path
    # usersコントローラのindexアクションを...
    assert_select "a[href=?]", user_path(@user)
    assert_select "a[href=?]", edit_user_path(@user)    
    assert_select "a[href=?]", logout_path
  end
end
```