22.用户个人中心
- 本系列文章为
laracasts.com
的系列视频教程——Let's Build A Forum with Laravel and TDD 的学习笔记。若喜欢该系列视频,可去该网站订阅后下载该系列视频, 支持正版 ;- 视频源码地址:github.com/laracasts/Lets-Build-a-...;
- 本项目为一个 forum(论坛)项目,与本站的第二本实战教程 《Laravel 教程 - Web 开发实战进阶》 类似,可互相参照。
本节说明
- 对应视频第 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);
}
}
运行测试显然会失败:
先来增加路由:
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()
{
}
}
再次运行测试:
仍然失败,所以我们要补充完整控制器内容:
.
use App\User;
public function show(User $user)
{
return view('profiles.show',[
'profileUser'=> $user
]);
}
.
并且新建视图文件:
forum\resources\views\profiles\show.blade.php
@extends('layouts.app')
@section('content')
{{ $profileUser->name }}
@endsection
再次运行测试:
由于隐性路由模型绑定的缘故:
Route::get('/profiles/{user}','ProfilesController@show');
我们期望的路由片段类似于:/profiles/1
,{user}
片段对应的是$user
的id
属性,但我们期望的是$user
的name
属性。所以我们仿照Channel
模型改变默认路由片段对应的属性值,改变User
对应的默认属性值为name
:
forum\app\User.php
.
.
public function getRouteKeyName()
{
return 'name';
}
}
再次测试,测试通过:
这意味着我们访问 forum.test/profiles/NoNo1 会看到如下页面:
可以看到页面十分简陋,让我们略微丰富一下:
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
略微好了点:
测试仍然是通过的:
接下来我们想把用户相关的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();
}
}
运行测试,测试通过:
刷新页面:
现在我们还有一个地方需要处理,那就是给页面加上分页:
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>
.
.