欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

[Laravel 5 教程学习笔记] 二十一、同步标签 有大用 有大大用

shiping1 的头像

看过前一节的应该知道,当时只做了发布博客时添加标签的操作,而当保存修改时,修改标签的操作并没有实现,所以这一节来接着完成前一节的工作,修改博客时同步标签。

 

首先我们把 store() 方法中添加标签的那段代码拷贝到 update() 方法中:


  1. public function update(Article $article, ArticleRequest $request){

  2. $article->update($request->all());

  3. $article->tags()->attach($request->input('tag_list'));

  4. return redirect('articles');

  5. }

这时,测试修改博客,比如原来的博客有 PHP、Python、Go 三个标签,现在编辑的时,删除其他两个,只留下PHP,然后保存修改。打开刚修改的博客详细页,发现更加糟糕,不但之前的标签没有去掉,反而多出了一个标签,这显然不是我们想要的。

我们有好几种方法可以解决该问题。1、通过设置 MySql 中 article_tag 表 article_id 与tag_id 对的唯一性,这样就可以确保标签的唯一,这只是一个可选的方法。2、我们这里采用一种不同的方法,我们想实现修改时传递给修改方法的标签ID数组是该博客唯一的标签ID数组,我们希望这种方法是可行的,因此同步(sync)就是我们这里的关键词。

我们这里这需要修改 update() 方法中的一个关键词即可:


  1. public function update(Article $article, ArticleRequest $request){

  2. $article->update($request->all());

  3. $article->tags()->sync($request->input('tag_list'));

  4. return redirect('articles');

  5. }

sync() 方法可以确保其传递的参数数组是唯一与该博客关联的标签的ID,而其它的都会被删除。

用命令行工具或者其他数据库管理工具把之前的标签清空,然后重新编辑博客试试吧。

注意:attach() 是添加,detach() 是删除,而 sync() 是同步。

通过上面的方法,我们已经实现了修改博客时同步博客标签的功能,下面来做一下代码的精简工作。

创建一个新的方法 syncTags(),用于同步博客的标签,然后修改 update() 中同步标签的代码:


  1. public function update(Article $article, ArticleRequest $request){

  2. $article->update($request->all());

  3. $this->syncTags($article, $request->input('tag_list'));

  4. return redirect('articles');

  5. }

  6.  

  7. // 同步标签

  8. private function syncTags(Article $article, array $tags){

  9. $article->tags()->sync($tags);

  10. }

接着修改 create() 方法中添加标签的代码,也使用 syncTags() 方法:


  1. public function store(ArticleRequest $request){

  2. $article = Auth::user()->articles()->create($request->all());

  3. $this->syncTags($article, $request->input('tag_list'));

  4. flash()->overlay('文章发布成功', 'Good Job');

  5. return redirect('articles');

  6. }

下面,我们把创建一篇新博客的代码提出,放到一个新的方法 createArticle() 中:


  1. public function create(){

  2. $tags = \App\Tag::lists('name', 'id');

  3. return view('articles.create', compact('tags'));

  4. }

  5.  

  6. //发布新的文章

  7. private function createArticle(ArticleRequest $request){

  8. $article = Auth::user()->articles()->create($request->all());

  9. $this->syncTags($article, $request->input('tag_list'));

  10. return $article;

  11. }

下面贴上 ArticlesController.php 文件的全部代码,看看是不是很简洁呢?


  1. <?php namespace App\Http\Controllers;

  2.  

  3. // 这里需要导入命名空间

  4. use App\Article;

  5. use App\Http\Requests;

  6. use App\Http\Controllers\Controller;

  7.  

  8. use Carbon\Carbon;

  9. //use Request;

  10. use App\Http\Requests\ArticleRequest;

  11. use Illuminate\Http\Request;

  12. use Auth;

  13.  

  14. class ArticlesController extends Controller {

  15.  

  16. public function __construct(){

  17. //除了主页之外

  18. $this->middleware('auth', ['except' => ['index', 'show']]);

  19. //只有发布页

  20. //$this->middleware('auth', ['only' => 'create']);

  21. }

  22.  

  23. public function index(){

  24.  

  25. $articles = Article::latest('published_at')->published()->get();

  26. return view('articles.index', compact('articles'));

  27. }

  28.  

  29. public function show(Article $article){

  30. return view('articles.show', compact('article'));

  31. }

  32.  

  33. public function create(){

  34. $tags = \App\Tag::lists('name', 'id');

  35. return view('articles.create', compact('tags'));

  36. }

  37.  

  38. public function store(ArticleRequest $request){

  39. $this->createArticle($request);

  40. flash()->overlay('文章发布成功', 'Good Job');

  41. return redirect('articles');

  42. }

  43.  

  44. public function edit(Article $article){

  45. $tags = \App\Tag::lists('name', 'id');

  46. return view('articles.edit', compact('article', 'tags'));

  47. }

  48.  

  49. public function update(Article $article, ArticleRequest $request){

  50. $article->update($request->all());

  51. $this->syncTags($article, $request->input('tag_list'));

  52. return redirect('articles');

  53. }

  54.  

  55. private function syncTags(Article $article, array $tags){

  56. $article->tags()->sync($tags);

  57. }

  58.  

  59. //发布新的文章

  60. private function createArticle(ArticleRequest $request){

  61. $article = Auth::user()->articles()->create($request->all());

  62. $this->syncTags($article, $request->input('tag_list'));

  63. return $article;

  64. }

  65. }


 
转载请注明来源:[Laravel 5 教程学习笔记] 二十一、同步标签 - Specs' Blog-就爱PHP

本文共 6 个回复

  •  

    Randy 2015/08/17 11:01

     快更新啊

  •  

    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,烦请教楼主如何解决。

  •  

    皇帝 2015/09/13 23:38

    不错,顶一下! 


普通分类: