Menu

22.用户个人中心

本节说明

  • 对应视频第 22 小节:A User Has A Profile

本节内容

本节我们来建立用户的 profile 功能。首先新建测试文件:
forum\tests\Feature\ProfilesTest.php

<?php

namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;

class ProfilesTest extends TestCase
{
    use DatabaseMigrations;

    /** @test */
    public function a_user_has_a_profile()
    {
        $user = create('App\User');

        $this->get("/profiles/{$user->name}")
            ->assertSee($user->name);
    }
}

运行测试显然会失败:
file
先来增加路由:
forum\routes\web.php

.
.
Route::get('/profiles/{user}','ProfilesController@show');

再来新建控制器并增加show()方法:

$  php artisan make:controller ProfilesController

forum\app\Http\Controllers\ProfilesController.php

<?php

namespace App\Http\Controllers;

class ProfilesController extends Controller
{
    public function show()
    {

    }
}

再次运行测试:
file
仍然失败,所以我们要补充完整控制器内容:

.
public function show()
{
    return view('profiles.show',[
        'profileUser'=> $user
    ]);
}
.

并且新建视图文件:
forum\resources\views\profiles\show.blade.php

@extends('layouts.app')

@section('content')
    {{ $profileUser->name }}
@endsection

再次运行测试:
file
由于隐性路由模型绑定的缘故:

Route::get('/profiles/{user}','ProfilesController@show');

我们期望的路由片段类似于:/profiles/1{user}片段对应的是$userid属性,但我们期望的是$username属性。所以我们仿照Channel模型改变默认路由片段对应的属性值,改变User对应的默认属性值为name
forum\app\User.php

.
.
    public function getRouteKeyName()
    {
        return 'name';
    }
}

再次测试,测试通过:
file
这意味着我们访问 http://forum.test/profiles/NoNo1 会看到如下页面:
file
可以看到页面十分简陋,让我们略微丰富一下:
forum\resources\views\profiles\show.blade.php

@extends('layouts.app')

@section('content')
    <div class="container">
        <div class="page-header">
            <h1>
                {{ $profileUser->name }}
                <small>注册于{{ $profileUser->created_at->diffForHumans() }}</small>
            </h1>
        </div>
    </div>
@endsection

略微好了点:
file
测试仍然是通过的:
file
接下来我们想把用户相关的Thread显示出来。按照惯例,先建立测试:
forum\tests\Feature\ProfilesTest.php

.
.
/** @test */
public function profiles_display_all_threads_created_by_the_associated_user()
{
    $user = create('App\User');

    $thread = create('App\Thread',['user_id' => $user->id]);

    $this->get("/profiles/{$user->name}")
        ->assertSee($thread->title)
        ->assertSee($thread->body);
}
.

补充完视图:
forum\resources\views\profiles\show.blade.php

@extends('layouts.app')

@section('content')
    <div class="container">
        <div class="page-header">
            <h1>
                {{ $profileUser->name }}
                <small>注册于{{ $profileUser->created_at->diffForHumans() }}</small>
            </h1>
        </div>

        @foreach($profileUser->threads as $thread)
            <div class="panel panel-default">
                <div class="panel-heading">
                    <div class="level">
                        <span class="flex">
                            <a href="#">{{ $thread->creator->name }}</a> 发表于
                            {{ $thread->title }}
                        </span>

                        <span>{{ $thread->created_at->diffForHumans() }}</span>
                    </div>
                </div>

                <div class="panel-body">
                    {{ $thread->body }}
                </div>
            </div>
        @endforeach
    </div>
@endsection

我们使用了threads模型关联关系,但此时关联关系还未建立。前往建立:
forum\app\User.php

.
.
    public function threads()
    {
        return $this->hasMany(Thread::class)->latest();
    }
}

运行测试,测试通过:
file
刷新页面:
file
现在我们还有一个地方需要处理,那就是给页面加上分页:
forum\resources\views\profiles\show.blade.php

@extends('layouts.app')

@section('content')
    <div class="container">
        <div class="page-header">
            <h1>
                {{ $profileUser->name }}
                <small>注册于{{ $profileUser->created_at->diffForHumans() }}</small>
            </h1>
        </div>

        @foreach($threads as $thread)  -->此处修改
            <div class="panel panel-default">
                <div class="panel-heading">
                    <div class="level">
                        <span class="flex">
                            <a href="#">{{ $thread->creator->name }}</a> 发表于
                            {{ $thread->title }}
                        </span>

                        <span>{{ $thread->created_at->diffForHumans() }}</span>
                    </div>
                </div>

                <div class="panel-body">
                    {{ $thread->body }}
                </div>
            </div>
        @endforeach

        {{ $threads->links() }}   -->此处加上分页链接
    </div>
@endsection

修改控制器:
forum\app\Http\Controllers\ProfilesController.php

<?php

namespace App\Http\Controllers;

use App\User;

class ProfilesController extends Controller
{
    public function show(User $user)
    {
        return view('profiles.show',[
            'profileUser'=> $user,
            'threads' => $user->threads()->paginate(10)
        ]);
    }
}

最后,我们需要在出现用户名的页面给用户名加上链接,跳转到用户的profile页面。我们先为profile路由定义别名:
forum\routes\web.php

.
.
Route::get('/profiles/{user}','ProfilesController@show')->name('profile');

为页面加上链接:
forum\resources\views\profiles\show.blade.php

.
.
<span class="flex">
    <a href="{{ route('profile',$thread->creator) }}">{{ $thread->creator->name }}</a> 发表于
    {{ $thread->title }}
</span>
.
.

forum\resources\views\threads\reply.blade.php

.
.
<h5 class="flex">
    <a href="{{ route('profile',$reply->owner) }}"> {{ $reply->owner->name }}</a>
    回复于
    {{ $reply->created_at->diffForHumans() }}
</h5>
.
.

forum\resources\views\threads\show.blade.php

.
.
<div class="panel-heading">
    <a href="{{ route('profile',$thread->creator) }}">{{ $thread->creator->name }}</a>
    {{ $thread->title }}
</div>
.
.

本文章首发在 Laravel China 社区
上一篇 下一篇
讨论数量: 0
发起讨论


暂无话题~