[Laravel 5 Fundamentals] 23 – Syncing Tags
标签同步
前言
上一节,我们在 UI 上实现对 tag 的选择,并且可以创建多个 tag 。但是有瑕疵,今天我们就来看看瑕疵是什么,并解决它。
说明
开发环境:Windows 7
Laravel 版本: 5+
IDE: Phpstorm
上节课,我们实现了给文章打标签,并且可以打多个标签。结束的时候,感觉一切都还在接受范围,但是我提到有一个小瑕疵,不知读者有无发现。当你编辑文章想修改文章的标签的时候,发现可以修改,但是保存之后再看文章,标签没变,还是之前的标签。这是因为什么?
本节的内容比较简单,专门解决这个小瑕疵。解决之前,你最好先看下这个瑕疵。
数据库检查
明明修改了,为什么没变,我要娶数据库里查看一番!
sqlite> select * fromarticles;1|1|2016-03-20 15:05:18|2016-03-20 15:05:18|谭晓龙创建的文章|真的是|2016-03-28 00:00:002|1|2016-04-23 07:00:13|2016-04-23 07:00:13|flashmessage|hello ~ flashmessage|2016-04-25 00:00:003|1|2016-04-23 07:07:34|2016-04-23 07:07:34|flashtest|flashtest|2016-04-25 00:00:004|1|2016-04-23 07:37:10|2016-04-23 07:37:10|session::put|session::put|2016-04-25 00:00:005|1|2016-04-23 07:59:52|2016-04-23 07:59:52|托尔斯泰|托尔斯泰|2016-04-25 00:00:006|1|2016-04-23 08:03:42|2016-04-23 08:03:42|按时打算asda|阿斯达速冻|2016-04-25 00:00:007|1|2016-04-23 08:05:52|2016-04-23 08:05:52|asdasd|asdasdas|2016-04-25 00:00:008|1|2016-04-23 08:21:58|2016-04-23 08:21:58|autodisappear|autodisappear|2016-04-25 00:00:009|1|2016-04-23 08:39:20|2016-04-23 08:39:20|asd|asdasd|2016-04-25 00:00:0010|1|2016-05-01 15:26:08|2016-05-08 14:17:44|asd|asdasdasdasd|2016-05-16 00:00:00sqlite> select * fromarticle_tagwherearticle_id = 10;10|2|2016-05-01 15:26:08|2016-05-01 15:26:0810|3|2016-05-01 15:26:08|2016-05-01 15:26:08
你看哈,我刚才重新编辑的文章是 id 号为 10 的文章,文章名为 asd ,比较朴实无华。在编辑页删了一个标签,原来有两个,还剩一个按理说。
然后我又通过 select * from article tag where articleid = 10 查询了一下 id 为 10 的文章的标签,你看哈,还是两个,他们的标签号分别为 2 和 3 。还是两个,没删掉。为什么呢?
找原因
文章更新的方法是 ArticleControlle.php 里的 updat() 方法,对吧?看一下该方法,相比较 store() 好像少了点什么,为什么跟 store() 方法比较,因为他们的过程差不多。在 store() 方法中比 updat() 方法多了一个 tags->attach() 这个过程。我们试试把该语句添加到 update() 方法管用不管用:
public function update($id,ArticleRequest $request){ $article=Article::findOrFail($id); $article->update($request->all()); $article->tags()->attach($request->input('tag_list')); return redirect('articles'); }
再去文章更新的页面修改一下文章的标签,保存之后再查看文章,发现标签多了。。。
其实细想一下,这个 $article 的 tags attach 的是什么?是 input(‘tag_list’) 里面的标签,相当于又把新编辑的对应该文章的标签存到了数据库。不信的话,你再通过 sqlit3 命令去查询一下你刚才编辑的文章的 tag 。肯定变多了。
按照这个思路的话,我们需要把原数据库中存储的 tag 进行删除,然后再添加新的标签,没错,就是这个逻辑。
Laravel 里除了 attach 这个方法外,还有 attach 的反方法 detach ,通过 detach 我们可以删除指定的标签,你可以做个实验,不过 detach 不是我们要讲的。
sync 方法
面对上面的瑕疵,我们的解决思路是先删干净数据库里文章对应的 tag , 然后再给文章添加 tag 。相当于,我们先 detach ,然后再 attach 。
不过, Laravel 还有一个方法叫 sync 。敏感的同学已经能脑补它的全称了,没错 synchronize ,“同步” 的意思。当你把 attach 方法直接修改为 sync ,保存后再编辑文章,修改标签,保存再查看文章,一切都恢复正常了:
public function update($id,ArticleRequest $request){ $article=Article::findOrFail($id); $article->update($request->all()); $article->tags()->sync($request->input('tag_list')); return redirect('articles'); }
所以说, attach 是添加标签,或者绑定标签; detach 是解除标签,或删除标签; sync 是同步标签,或者说是标签的更新。
同理,把 store() 方法里的 attach 也换成 sync 。
总结
今天解决了一个小瑕疵,并对比了三种方法,分别是 attach detach 和 sync 。
attach 就是给文章添加 tag ,绑定 tag ,追加 tag
detach 就是给文章解绑指定的 tag ,删除 tag
sync 就是用来对文章的 tag 进行同步的。
上一篇: 【Little Demo】左右按钮tab选项卡双切换的实例代码
下一篇: php常用正则
推荐阅读
-
[Laravel 5 Fundamentals] 21 – Many-to-Many Relationships and Tags
-
[Laravel 5 Fundamentals] 20 – Flash Message
-
[Laravel 5 Fundamentals] 25 – When You Want a View Partial to Always Receive Data
-
Laravel 5:多对多,实现文章和tags
-
[Laravel 5 Fundamentals] 23 – Syncing Tags
-
[Laravel 5 Fundamentals] 23 – Syncing Tags
-
Laravel 5:多对多,实现文章和tags
-
[Laravel 5 Fundamentals] 26 – The Service Container
-
[Laravel 5 Fundamentals] 22 – Selecting Tags From the UI