自作アプリを作成する ユーザー削除

###db/migrate/[timestamp]_add_admin_to_users.rb
```db/migrate/[timestamp]_add_admin_to_users.rb
class AddAdminToUsers < ActiveRecord::Migration[6.0]
  def change
    add_column :users, :admin, :boolean, default: false
  end
end
```
```
rails db:migrate
```
###db/seeds.rb
```db/seeds.rb
# メインのサンプルユーザーを1人作成する
User.create!(name:  "Example User",
             email: "example@railstutorial.org",
             password:              "foobar",
             password_confirmation: "foobar",
             admin: true)
# admin権限をつける

# 追加のユーザーをまとめて生成する
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
```

```
$ rails db:migrate:reset
$ rails db:seed
```
###app/views/users/_user.html.erb
```app/views/users/_user.html
.erb

<li>
  <%= gravatar_for user, size: 50 %>
  <%= link_to user.name, user %>
  <% if current_user.admin? && !current_user?(user) %>
    | <%= link_to "delete", user, method: :delete,
                                  data: { confirm: "You sure?" } %>
  <% end %
</li>
```
###app/controllers/users_controller.rb
```app/controllers/users_controller.rb
class UsersController < ApplicationController
  before_action :logged_in_user, only: [:index, :edit, :update, :destroy]
  before_action :correct_user,   only: [:edit, :update]
  before_action :admin_user,     only: :destroy

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

  def show
    @user = User.find(params[:id])
  end
 
  def new
    @user = User.new
  end
  
  def create
    @user = User.new(user_params) # 実装は終わっていないことに注意!
    if @user.save
      log_in @user
      flash[:success] = "ようこそ自作アプリへ成功しました！"
      redirect_to @user
    else
      render 'new'
    end
  end
  
  def edit
    @user = User.find(params[:id])
  end
  
  def update
    @user = User.find(params[:id])
    if @user.update(user_params)
      flash[:success] = "Profile updated"
      redirect_to @user
    else
      render 'edit'
    end
  end

  def destroy
    User.find(params[:id]).destroy
    # データベースから探して削除する
    flash[:success] = "User deleted"
    redirect_to users_url
    # わからない
  end
  
  private
  
    def user_params
      params.require(:user).permit(:name, :email, :password, 
                                     :password_confirmation)
    end
    
    def logged_in_user
      unless logged_in?
        store_location
        flash[:danger] = "Please log in."
        redirect_to login_url
      end
    end
    
    # 正しいユーザーかどうか確認
    def correct_user
      @user = User.find(params[:id])
      redirect_to(root_url) unless @user == current_user
    end

　　　　　　　　# 管理者かどうか確認
    def admin_user
      redirect_to(root_url) unless current_user.admin?
      #管理者ではない時ホーム画面に移動する
    end

end
```
###test/fixtures/users.yml
```test/fixtures/users.yml
michael:
# テストデータ
  name: Michael Example
  email: michael@example.com
  password_digest: <%= User.digest('password') %>
  admin: true
  # 管理者
  
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 %>
```
###test/controllers/users_controller_test.rb
```test/controllers/users_controller_test.rb
require 'test_helper'

class UsersControllerTest < ActionDispatch::IntegrationTest
  
  def setup
    @user = users(:michael)
  end
  
  test "should get new" do
    get signup_path
    # users/newでgetリクエスト
    assert_response :success
    # リクエストを受けることができましたか？
  end
  
  test "should redirect edit when not logged in" do
  # ログイン無しでは編集できないテスト
    get edit_user_path(@user)
    # 編集ページへの移動を要求
    assert_not flash.empty?
    # flashに中身はあるか？
    assert_redirected_to login_url
    # ログインページに自動的に移動させる
  end

  test "should redirect update when not logged in" do
  # ログイン無しでは上書きできないテスト
    patch user_path(@user), params: { user: { name: @user.name,
                                              email: @user.email } }
    # 情報を上書きする
    assert_not flash.empty?
    # flashに中身はあるか？
    assert_redirected_to login_url
    # 自動的にログインページに移動させる
  end
  
  test "should redirect destroy when not logged in" do
    assert_no_difference 'User.count' do
    # 削除されてデータベースを数えて減ってないか？
      delete user_path(@user)
      # ユーザーを削除する
    end
    assert_redirected_to login_url
    # ログインページに自動的に移動しているか？
  end

  test "should redirect destroy when logged in as a non-admin" do
    log_in_as(@other_user)
    # ログインさせる
    assert_no_difference 'User.count' do
    # データベースの数に違いはないよね？
      delete user_path(@user)
      # 削除する
    end
    assert_redirected_to root_url
    # ホーム画面に自動的に移動しているか？
  end
end
```
###test/integration/users_index_test.rb
```test/integration/users_index_test.rb
class UsersIndexTest < ActionDispatch::IntegrationTest

  def setup
    @admin     = users(:michael)
    @non_admin = users(:archer)
  end
  
  test "index as admin including pagination and delete links" do
    log_in_as(@admin)
    # 管理者でログイン
    get users_path
    # ユーザーページ移動を要求
    assert_template 'users/index'
    # 全ユーザーを表示されているか？
    assert_select 'div.pagination'
    # htmlにpaginateが入力されているか？
    first_page_of_users = User.paginate(page: 1)
    # 全ユーザーの１ページを代入
    first_page_of_users.each do |user|
    # 1ページ内から一つずつ取り出す
      assert_select 'a[href=?]', user_path(user), text: user.name
      # 名前を表示されているか？
      unless user == @admin
      # 管理者でなければ
        assert_select 'a[href=?]', user_path(user), text: 'delete'
        # deleteを表示されるか？
      end
    end
    assert_difference 'User.count', -1 do
    # 削除されているかを確認？
      delete user_path(@non_admin)
      # 管理者以外を削除
    end
  end

  test "index as non-admin" do
    log_in_as(@non_admin)
    # 管理者以外がログイン
    get users_path
    # ユーザーページへ移動
    assert_select 'a', text: 'delete', count: 0
    # deleteが表示されていないかを確認
  end
end
```

```
ubuntu:~/environment/my_app (updating-users) $ rails t
Running via Spring preloader in process 8283
Run options: --seed 42332

# Running:

.....................E

Error:
UsersIndexTest#test_index_as_admin_including_pagination_and_delete_links:
NoMethodError: undefined method `email' for nil:NilClass
    test/test_helper.rb:38:in `log_in_as'
    test/integration/users_index_test.rb:11:in `block in <class:UsersIndexTest>'


rails test test/integration/users_index_test.rb:10

.........

Finished in 2.588285s, 11.9770 runs/s, 28.9767 assertions/s.
31 runs, 75 assertions, 0 failures, 1 errors, 0 skips
```
```
NoMethodError: undefined method `email' for nil:NilClass
```
@adminが@userになっていたためだった。

###デプロイの後
```
$ rails test
$ git push heroku
$ heroku pg:reset DATABASE
  アプリ名を入力する
$ heroku run rails db:migrate
$ heroku run rails db:seed
```