Laravel教程二十一 同步标签

首先我们把 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,然后保存修改。打开刚修改的博客详细页,发现更加糟糕,不但之前的标签没有去掉,反而多出了一个标签,这显然不是我们想要的。

Laravel教程二十一 同步标签

我们有好几种方法可以解决该问题。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教程二十一 同步标签:等您坐沙发呢!

发表评论

表情
还能输入210个字