看过前一节的应该知道,当时只做了发布博客时添加标签的操作,而当保存修改时,修改标签的操作并没有实现,所以这一节来接着完成前一节的工作,修改博客时同步标签。
首先我们把 store()
方法中添加标签的那段代码拷贝到 update()
方法中:
public function update(Article $article, ArticleRequest $request){ $article->update($request->all()); $article->tags()->attach($request->input('tag_list')); return redirect('articles'); }
这时,测试修改博客,比如原来的博客有 PHP、Python、Go 三个标签,现在编辑的时,删除其他两个,只留下PHP,然后保存修改。打开刚修改的博客详细页,发现更加糟糕,不但之前的标签没有去掉,反而多出了一个标签,这显然不是我们想要的。
我们有好几种方法可以解决该问题。1、通过设置 MySql 中 article_tag
表 article_id
与 tag_id
对的唯一性,这样就可以确保标签的唯一,这只是一个可选的方法。2、我们这里采用一种不同的方法,我们想实现修改时传递给修改方法的标签ID数组是该博客唯一的标签ID数组,我们希望这种方法是可行的,因此同步(sync
)就是我们这里的关键词。
我们这里这需要修改 update()
方法中的一个关键词即可:
public function update(Article $article, ArticleRequest $request){ $article->update($request->all()); $article->tags()->sync($request->input('tag_list')); return redirect('articles'); }
sync()
方法可以确保其传递的参数数组是唯一与该博客关联的标签的ID,而其它的都会被删除。
用命令行工具或者其他数据库管理工具把之前的标签清空,然后重新编辑博客试试吧。
attach()
是添加,detach()
是删除,而 sync()
是同步。通过上面的方法,我们已经实现了修改博客时同步博客标签的功能,下面来做一下代码的精简工作。
创建一个新的方法 syncTags()
,用于同步博客的标签,然后修改 update()
中同步标签的代码:
public function update(Article $article, ArticleRequest $request){ $article->update($request->all()); $this->syncTags($article, $request->input('tag_list')); return redirect('articles'); } // 同步标签 private function syncTags(Article $article, array $tags){ $article->tags()->sync($tags); }
接着修改 create()
方法中添加标签的代码,也使用 syncTags()
方法:
public function store(ArticleRequest $request){ $article = Auth::user()->articles()->create($request->all()); $this->syncTags($article, $request->input('tag_list')); flash()->overlay('文章发布成功', 'Good Job'); return redirect('articles'); }
下面,我们把创建一篇新博客的代码提出,放到一个新的方法 createArticle()
中:
public function create(){ $tags = \App\Tag::lists('name', 'id'); return view('articles.create', compact('tags')); } //发布新的文章 private function createArticle(ArticleRequest $request){ $article = Auth::user()->articles()->create($request->all()); $this->syncTags($article, $request->input('tag_list')); return $article; }
下面贴上 ArticlesController.php 文件的全部代码,看看是不是很简洁呢?
<?php namespace App\Http\Controllers; // 这里需要导入命名空间 use App\Article; use App\Http\Requests; use App\Http\Controllers\Controller; use Carbon\Carbon; //use Request; use App\Http\Requests\ArticleRequest; use Illuminate\Http\Request; use Auth; class ArticlesController extends Controller { public function __construct(){ //除了主页之外 $this->middleware('auth', ['except' => ['index', 'show']]); //只有发布页 //$this->middleware('auth', ['only' => 'create']); } public function index(){ $articles = Article::latest('published_at')->published()->get(); return view('articles.index', compact('articles')); } public function show(Article $article){ return view('articles.show', compact('article')); } public function create(){ $tags = \App\Tag::lists('name', 'id'); return view('articles.create', compact('tags')); } public function store(ArticleRequest $request){ $this->createArticle($request); flash()->overlay('文章发布成功', 'Good Job'); return redirect('articles'); } public function edit(Article $article){ $tags = \App\Tag::lists('name', 'id'); return view('articles.edit', compact('article', 'tags')); } public function update(Article $article, ArticleRequest $request){ $article->update($request->all()); $this->syncTags($article, $request->input('tag_list')); return redirect('articles'); } private function syncTags(Article $article, array $tags){ $article->tags()->sync($tags); } //发布新的文章 private function createArticle(ArticleRequest $request){ $article = Auth::user()->articles()->create($request->all()); $this->syncTags($article, $request->input('tag_list')); return $article; } }
该篇属于专题:《Laravel 5 基础视频教程学习笔记》
Randy 2015/08/17 11:01
Specs 2015/08/17 16:31
@ 后面好像没什么了。。
charo 2015/09/12 22:00
改用了syncTags()方法后,报错:Argument 2 passed to App\Http\Controllers\ArticlesController::syncTags() must be of the type array, null given, called in N:\MyWeb\laravel5\app\Http\Controllers\ArticlesController.php on line 57 and defined,烦请教楼主如何解决。
Specs 2015/09/12 22:03
@ 看提示是你第二个参数没传值
皇帝 2015/09/13 23:38
不错,顶一下!
charo 2015/09/14 23:05
@ 用dd()查了一下第二个参数,果然输出是null, 最后找到是模板中有个'tag_list'输入成了'tags_list' ,造成了input('tag_list')输出变成了null, 感谢楼主的解答,谢谢!