laravelpro_ユーザープロフィール画面を作成する

13ユーザープロフィール画面を作成する

完成形の画面イメージは以下です。

Twitterのような、フォロー、フォロワー数や、ユーザのメモ内容が見られるページになっています。

このページにはタイムラインのユーザー名の部分をリンクにし、リンクをクリックするとこのページに飛ぶようにします。

フォロー機能を実装するにあたりテーブルを1つ作成します。

「フォローしている/フォローされている」の関係は、多対多の関係です。

また、最終課題である「お気に入り機能」も、多対多の関係です。

1対多・多対多の関係は必ず復習してください。

usersとusersのフォロー関係のレコードを保存する中間テーブル「follow」を作成しましょう。

public function up(): void {
    Schema::create('follow', function (Blueprint $table) {
        $table->id();
        $table->integer('user_id')->nullable(false);
        $table->integer('follow_id')->nullable(false);
        $table->integer('invalid')->default(0);
        $table->timestamps();
    });
}

カラムは大きく「user_id」「follow_id」になります。

user_idが2、follow_idが1であるとき、usersのIDが2であるユーザーがusersのIDが1であるユーザーをフォローしているという意味になります。

逆を言うとusersのIDが2であるユーザーはusersのIDが1であるユーザーにフォローされているという意味になります。

つまり、usersのIDが1であるユーザーのフォロー数を数えたければ、「follow」テーブルのuser_idが1であるレコード数を取得するとユーザーのフォロー数を取得することができます。

フォロワー数を数えたければ、「follow」テーブルのfollow_idが1であるレコード数を数えるとフォロワー数をカウントすることができます。

それぞれをコードで表せと以下のようになります。

// フォロー数を取得
Follow::where('user_id', $user_id)->where('invalid', 0)->count();

// フォロワー数を取得
Follow::where('follow_id', $user_id)->where('invalid', 0)->count();

count()メソッドでレコード数を取得することができます。

これでフォロー・フォロワー数を取得することができました。

では実際にページを作成していきましょう。

timeline.blade.php

<div class="memo_show">@foreach($memo_info as $memo) 
<div class="memo_item">
<div class="memo_title">
<time>
  <a href="/user_profile/{{$memo->user_id}}">// 追記 ユーザー名:{{ $memo->name }} </a>{{$memo->created_at}}
</time>
<p>{{$memo->content}}</p>
</div>

コントローラを作成

php artisan make:controller UserProfileController

UserProfileController.php

public function show($user_id) {
    // メモ一覧を取得
    $memo_info = Memo::where('user_id', $user_id)->where('invalid', 0)->get();
    // 対象のユーザー情報を取得
    $user_info = User::find($user_id);

    return view('user_profile')
        ->with('memo_info', $memo_info)
        ->with('user_info', $user_info);
}

web.php

Route::get('/user_profile/{user_id}',
'App\\Http\\Controllers\\UserProfileController@show');

user_profile.blade.php

@extends('layouts.base') @section('content') 
<div class="user_profile_area"> 
  <form action="/follow/{{$user_info->id}}" method="post">@csrf 
    <input class="follow-btn" type="submit" value="フォローする">
  </form>
  <h2>ユーザー名:{{$user_info->name}}</h2>
  <ul class="profile_list">
    <li>フォロー数:0</li>
    <li>フォロワー数:0</li>
    <li>お気に入り数:0</li>
  </ul>
  <div class="memo_show" style="margin: auto">@foreach($memo_info as $memo) 
    <div class="memo_item">
      <div class="memo_title">
        <time>{{$memo->created_at}}</time>
        <p>{{$memo->content}}</p>
      </div>@if($user_info->id === $current_user_id) 
      <div class="btn_area">
        <div class="edit_form">
          <form action="{{ asset('/edit/'.$memo->id) }}" method="get">@csrf 
            <input type="submit" value="編集">
          </form>
        </div>
        <div class="del_area">
          <form action="{{ asset('/delete') }}" method="post">@csrf 
            <input type="hidden" name="delete_id" value="{{$memo->id}}">
            <input type="submit" value="削除">
          </form>
        </div>
      </div>@endif 
    </div>@endforeach 
  </div>
</div>@endsection

style.css(追記)

.follow-btn {
    border: #1da1f2 solid 3px;
    padding: 5px 10px;
    border-radius: 3px;
    background-color: transparent;
    font-weight: bold;
}
.unfollow-btn {
    border: #1da1f2 solid 3px;
    padding: 5px 10px;
    border-radius: 3px;
    background-color: #1da1f2;
    color: #fff;
    font-weight: bold;
}

ではページを読み込んで「タイムラインページ」を開いてください。

メモのユーザー名の部分がリンクになったとおもいます。

クリックしてみましょう。

クリックしたユーザーのページに遷移できました。

クリックしたユーザーのメモを表示することができています。

メモ取得ロジックは前回と同じです。

では残りの

  1. フォロー機能の実装
  2. フォローボタンの切替
  3. フォロー解除機能の実装
  4. フォロー数の表示
  5. フォロワー数の表示

を実装してきましょう。

1.フォロー機能の実装

すでにURLは設定してあります。

user_profile.blade.php

<div class="user_profile_area"> 
<form action="/follow/{{$user_info->id}}" method="post">@csrf 
  <input class="follow-btn" type="submit" value="フォローする">
</form>

この部分でフォローするをクリックすると「/follow/user_id」に遷移します。

ここでのユーザーIDはログインしているユーザーのIDと一致するとは限りません。

UserProfileController.phpにメソッドを追記していきます。

public function followUser($follow_id) {
    $user_id = Auth::id();
    Follow::create(
        [
            'user_id' => $user_id,
            'follow_id' => $follow_id
        ]
    );
    return redirect('/user_profile/' . $follow_id);
}

$followでフォロー対象のusersのIDを取得しています。

その後、現在ログイン中のユーザーのIDを取得し「follow」テーブルに保存しています。

では実際にfollowUserメソッドが実行されるようにweb.phpに追記していきましょう。

Route::post('/follow/{follow_id}',
'App\\Http\\Controllers\\UserProfileController@followUser');

これでフォロー機能が実装出来ました。

それでは実際にフォローボタンをクリックしDBに保存されているか確認していきましょう。

ちゃんと入っていますね!

実際の数値は皆さんと違うと思います。

画面を見てみましょう。

DBに値は追加されていますがボタンはまだ「フォローする」になっています。

次はこれを切り替えられるようにしましょう。

2.フォローボタンの切替

user_profile.blade.phpを編集していきます。

@if($is_follow) 
<form action="/unfollow/{{$user_info->id}}" method="post">@csrf 
  <input class="unfollow-btn" type="submit" value="フォローを外す">
</form>@else 
<form action="/follow/{{$user_info->id}}" method="post">@csrf 
  <input class="follow-btn" type="submit" value="フォローする">
</form>@endif

UserProfileController.php

public function show($user_id) {
    // メモ情報を取得
    $memo_info = Memo::where('user_id', $user_id)->where('invalid', 0)->get();
    
    // ユーザー情報を取得
    $user_info = User::find($user_id);

    // 現在のユーザーIDを取得
    $current_user_id = Auth::id();

    // フォローしているかどうかを判別
    $is_follow = Follow::where('user_id', $current_user_id)
        ->where('follow_id', $user_id)
        ->where('invalid', 0)->exists();

    return view('user_profile')
        ->with('memo_info', $memo_info)
        ->with('is_follow', $is_follow)
        ->with('current_user_id', $current_user_id)
        ->with('user_info', $user_info);
}

注目すべきは$is_follow = Follow::where('user_id', $current_user_id)->where('follow_id', $user_id)->where('invalid', 0)->exists();この部分です。

最後のexists()ですが対象のレコードが存在するかどうかを判別します。

存在する場合は「true」存在しない場合は「false」が返り値となります。

users_idがログインしているユーザのIDでfollower_idが選択されたメモのユーザーIDであるレコード、つまり、ログイン中のユーザーが選択したメモのユーザーをフォローしているかどうかは判断します。

存在していた場合はtrue 存在しなかった場合はfalseになります。

ではページを読み込んでみましょう。

無事にフォローを外すボタンが表示されました。

次はフォロー解除機能を作っていきましょう。

3.フォロー解除機能の実装

user_profile.blade.phpにすでに遷移先URLは設定しています。

@if($is_follow) 
<form action="/unfollow/{{$user_info->id}}" method="post">@csrf 
  <input class="unfollow-btn" type="submit" value="フォローを外す">
</form>@else 
<form action="/follow/{{$user_info->id}}" method="post">@csrf 
  <input class="follow-btn" type="submit" value="フォローする">
</form>@endif

フォローを外すボタンをクリックすると「/unfollow/user_id」に遷移するようになっています。

ではUserProfileController.phpに追記しましょう。

public function unfollowUser($follow_id) {
    $user_id = Auth::id();
    Follow::where('user_id', $user_id)
        ->where('follow_id', $follow_id)
        ->update(['invalid' => 1]);
     
    return redirect('/user_profile/' . $follow_id);
}

一致するレコードの「invalid」を1に上書きして論理削除しています。

画面を読み込んで、フォロー解除ボタンをクリックしましょう。

ボタンが「フォローする」に変化しています。

DBを確認します。

無事に「invalid」に1が入っています。

これでフォロー削除機能が実装出来ました。

では続いてフォロー数を画面に表示できるように実装していきましょう。

4.フォロー数の表示

フォロー数を取得する処理は先ほど紹介しました。

// フォロー数を取得
Follow::where('user_id', $user_id)->where('invalid', 0)->count();

これでフォロー数を取得することができます。

ではこれを踏まえてメソッドに追記していきましょう。

public function show($user_id) {
    // メモ情報を取得
    $memo_info = Memo::where('user_id', $user_id)->where('invalid', 0)->get();
    
    // ユーザー情報を取得
    $user_info = User::find($user_id);

    // 現在のユーザーIDを取得
    $current_user_id = Auth::id();

    // フォロー数を取得
    $follow_count = Follow::where('user_id', $user_id)->where('invalid', 0)->count();
  
    // フォローしているかどうかを判別
    $is_follow = Follow::where('user_id', $current_user_id)
        ->where('follow_id', $user_id)
        ->where('invalid', 0)->exists();

    return view('user_profile')
        ->with('memo_info', $memo_info)
        ->with('follow_count', $follow_count)
        ->with('is_follow', $is_follow)
        ->with('current_user_id', $current_user_id)
            ->with('user_info', $user_info);
}

user_profile.blade.phpに追記します。

<ul class="profile_list">
  <li>フォロー数:{{$follow_count}}</li>// 追記
  <li>フォロワー数:0</li>
  <li>お気に入り数:0</li>
</ul>

ユーザーをフォローした後ログイン中のアカウントを開いてみましょう。

※ログイン中のユーザーのメモがないとログイン中ユーザー画面に遷移することはできません

フォロー数が1になっていますね。

これでフォロー数表示部分が実装出来ました。

ログイン中のユーザーの画面を開くときはフォローボタンを非表示にする処理を追加しておきましょう。

user_profile.blade.phpに追記してください。

@if($user_info->id !== $current_user_id) // 追記 @if($is_follow) 
<form action="/unfollow/{{$user_info->id}}" method="post">@csrf 
  <input class="unfollow-btn" type="submit" value="フォローを外す">
</form>@else 
<form action="/follow/{{$user_info->id}}" method="post">@csrf 
  <input class="follow-btn" type="submit" value="フォローする">
</form>@endif @endif // 追記

$user_info->idにはメモを記載したユーザーのIDが入っています。

$current_user_idには現在ログイン中のユーザーIDが入っています。

$user_info->id$current_user_idが一致しない時だけボタンを表示します。

一致する場合は自分の画面になるのでボタンを非表示にします。

最後にフォロワー数表示部分を作成していきます。

5.フォロワー数の表示

フォロワー数を取得する処理は先ほど作成した、

// フォロワー数を取得
Follow::where('follow_id', $user_id)->where('invalid', 0)->count();

です。

ではこれを踏まえてUserProfileController.phpに追記します。

public function show($user_id) {
    // メモ情報を取得
    $memo_info = Memo::where('user_id', $user_id)->where('invalid', 0)->get();
    
    // ユーザー情報を取得
    $user_info = User::find($user_id);
    
    // 現在のユーザーIDを取得
    $current_user_id = Auth::id();

    // フォロー数を取得
    $follow_count = Follow::where('user_id', $user_id)->where('invalid', 0)->count();

    // フォロワー数を取得
    $followed_count = Follow::where('follow_id', $user_id)->where('invalid', 0)->count();

    // フォローしているかどうかを判別
    $is_follow = Follow::where('user_id', $current_user_id)
        ->where('follow_id', $user_id)
        ->where('invalid', 0)->exists();

    return view('user_profile')
        ->with('memo_info', $memo_info)
        ->with('follow_count', $follow_count)
        ->with('followed_count', $followed_count)
        ->with('is_follow', $is_follow)
        ->with('current_user_id', $current_user_id)
        ->with('user_info', $user_info);
}

user_profile.blade.phpを追記します

<ul class="profile_list">
  <li>フォロー数:{{$follow_count}}</li>
  <li>フォロワー数:{{$followed_count}}</li>
  <li>お気に入り数:0</li>
</ul>

ではフォローしたユーザーを表示しましょう。

無事にフォロワー数が1になっています。

ここまでの内容をGitで管理するようにしましょう。

下記コマンドを実行してください。

// 初期化
git init

git add .
git commit -m "メモ共有機能"

// デフォルトのmasterブランチをmainブランチに名前を変更
git branch -M main

ここでも、リモートリポジトリの作成方法とpushの方法は、Gitの教材を参考にしてください。


投稿日

カテゴリー:

投稿者:

タグ:

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です