2016 版 Laravel 系列入门教程(五)【最适合中国人的 Laravel 教程】
本教程示例代码见: https://github.com/johnlui/Learn-Laravel-5
在任何地方卡住,最快的办法就是去看示例代码。
本文是本系列教程的完结篇,我们将一起给 Article 加入评论功能,让游客在前台页面可以查看、提交、回复评论,并完成后台评论管理功能,可以删除、编辑评论。Article 和评论将使用 Laravel Eloquent 提供的“一对多关系”功能大大简化模型见关系的开发复杂度。最终,我们将得到一个个人博客系统的雏形,并布置一个大作业,供大家实战练习。
本篇文章中我将会使用一些 Laravel 的高级功能,这些高级功能对新手理解系统是不利的,但却可以进一步提高熟手的开发效率。
回顾 Eloquent
前面我们已经说过,Laravel Eloquent ORM 是 Laravel 中最强大的部分,也是 Laravel 能如此流行最重要的原因。中文文档在: http://laravel-china.org/docs/5.1/eloquent
learnlaravel5/app/Article.php
就是一个最简单的 Eloquent Model 类:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
//
}
若想进一步了解 Eloquent,推荐阅读系列文章: 深入理解 Laravel Eloquent
开始构建评论系统
基础规划
我们需要新建一个表专门用来存放数据库,每条评论都属于某一篇文章。评论之间的层级关系比较复杂,本文为入门教程,主要是为了带领大家体验模型间关系,就不在做过多的规划,将“回复别人的评论”暂定为简单的在评论内容前面增加@john 这样的字符串。
建立 Model 类和数据表
创建名为 Comment 的 Model 类,并顺便创建附带的 migration,在 learnlaravel5 目录下运行命令:
php artisan make:model Comment -m
这样一次性建立了 Comment 类和 2016_06_03_220325_create_comments_table 两个文件。修改 migration 文件的 up 方法为:
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->increments('id');
$table->string('nickname');
$table->string('email')->nullable();
$table->string('website')->nullable();
$table->text('content')->nullable();
$table->integer('article_id');
$table->timestamps();
});
}
之后运行命令:
php artisan migrate
去数据库里瞧瞧,comments 表已经躺在那儿啦。
建立“一对多关系”
在 Article 模型中增加一对多关系的函数:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
public function hasManyComments()
{
return $this->hasMany('App\Comment', 'article_id', 'id');
}
}
搞定啦!Eloquent 中模型间关系就是这么简单!
构建前台 UI
让我们修改前台的视图文件,想办法把评论功能加入进去。
创建前台的 ArticleController 类
运行命令:
php artisan make:controller ArticleController
增加路由:
Route::get('article/{id}', 'ArticleController@show');
此处的 {id} 指代任意字符串,在我们的规划中,此字段为文章 ID,为数字,但是本行路由却会尝试匹配所有请求,所以当你遇到了奇怪的路由调用的方法跟你想象的不一样时,记得检查路由顺序。路由匹配方式为前置匹配:任何一条路由规则匹配成功,会立刻返回结果,后面的路由便没有了机会。
给 ArticleController 增加 show 函数:
public function show($id)
{
return view('article/show')->withArticle(Article::with('hasManyComments')->find($id));
}
创建前台文章展示视图
新建 learnlaravel5/resources/views/article/show.blade.php
文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Learn Laravel 5</title>
<link href="//cdn.bootcss.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<script src="//cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script>
<script src="//cdn.bootcss.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
</head>
<div id="content" style="padding: 50px;">
<h4>
<a href="/"><< 返回首页</a>
</h4>
<h1 style="text-align: center; margin-top: 50px;">{{ $article->title }}</h1>
<hr>
<div id="date" style="text-align: right;">
{{ $article->updated_at }}
</div>
<div id="content" style="margin: 20px;">
<p>
{{ $article->body }}
</p>
</div>
<div id="comments" style="margin-top: 50px;">
@if (count($errors) > 0)
<div class="alert alert-danger">
<strong>操作失败</strong> 输入不符合要求<br><br>
{!! implode('<br>', $errors->all()) !!}
</div>
@endif
<div id="new">
<form action="{{ url('comment') }}" method="POST">
{!! csrf_field() !!}
<input type="hidden" name="article_id" value="{{ $article->id }}">
<div class="form-group">
<label>Nickname</label>
<input type="text" name="nickname" class="form-control" style="width: 300px;" required="required">
</div>
<div class="form-group">
<label>Email address</label>