前一节学习了多对多关系模型,已经如何在Eloquent模型中表述它,现在我们来介绍通过界面选择来完成。
一、显示与创建标签
首先打开 /resources/views/articles/_form.blade.php 文件,在提交按钮的前面添加下面代码:
class="form-group">- {!! Form::label('tags', 'Tags:') !!}
- {!! Form::select('tags', $tags, null, ['class' => 'form-control', 'multiple']) !!}
然后修改 ArticlesController.php 文件中的
create()
方法:
- public function create(){
- $tags = \App\Tag::lists('name');
- return view('articles.create', compact('tags'));
- }
现在打开 http://laravel.dev/articles/create ,可以看到,多出了一个列出所有标签的多选框。
由于上一节我们只添加了一个标签,所以这里只列出了一个。下面我们通过
tinker
命令行继续创建几个标签:
- D:\wamp\www\laravel5>php artisan tinker
- Psy Shell v0.4.1 (PHP 5.5.12 鈥?cli) by Justin Hileman
- >>> \App\Tag::create(['name' => 'Java']);
- Illuminate\Database\Eloquent\MassAssignmentException with message 'name'
使用上面的命令发现,添加失败了,这个其实之前就介绍过,是Laravel的一种保护机制。我们打开Tag.php 文件,添加下面的代码:
- protected $fillable = [
- 'name',
- ];
然后退出
tinker
并重新打开:
- D:\wamp\www\laravel5>php artisan tinker
- Psy Shell v0.4.1 (PHP 5.5.12 鈥?cli) by Justin Hileman
- >>> \App\Tag::create(['name' => 'Java']);
- => <App\Tag #000000000e99479a00000000057c0183> {
- name: "Java",
- updated_at: "2015-08-02 00:34:40",
- created_at: "2015-08-02 00:34:40",
- id: 2
- }
- >>> \App\Tag::create(['name' => 'C##']);
- => <App\Tag #000000000e99479000000000057c0183> {
- name: "C##",
- updated_at: "2015-08-02 00:35:44",
- created_at: "2015-08-02 00:35:44",
- id: 3
- }
- >>> \App\Tag::create(['name' => 'Python']);
- => <App\Tag #000000000e99478c00000000057c0183> {
- name: "Python",
- updated_at: "2015-08-02 00:35:53",
- created_at: "2015-08-02 00:35:53",
- id: 4
- }
- >>> \App\Tag::create(['name' => 'Go']);
- => <App\Tag #000000000e99478800000000057c0183> {
- name: "Go",
- updated_at: "2015-08-02 00:36:01",
- created_at: "2015-08-02 00:36:01",
- id: 5
- }
默认情况下,使用
lists('name')
所得到的 key
值是以 0
开始的,而我们需要的是 key
值就是 value
的值,所以需要按这么那种写法:
- >>> \App\Tag::lists('name');
- => [
- "PHP",
- "Java",
- "C##",
- "Python",
- "Go"
- ]
- >>> \App\Tag::lists('name', 'name');
- => [
- "PHP" => "PHP",
- "Java" => "Java",
- "C##" => "C##",
- "Python" => "Python",
- "Go" => "Go"
- ]
现在修改 ArticlesController.php 中
create()
方法:
- public function create(){
- $tags = \App\Tag::lists('name', 'name');
- return view('articles.create', compact('tags'));
- }
这时刷新页面,查看源代码,可以看到已经得到了我们想要的结果。
二、添加结果处理
修改 ArticlesController.php 中的
store()
方法,打印出选择的标签:
- public function store(ArticleRequest $request){
- dd($request->input('tags'));
- Auth::user()->articles()->create($request->all());
- flash()->overlay('文章发布成功', 'Good Job');
- return redirect('articles');
- }
然后添加博客内容,选中所有的标签并点击添加按钮,却发现只打印出了一个标签,这是因为我们需要把标签作为数组才可以。修改模版文件:
class="form-group">- {!! Form::label('tags', 'Tags:') !!}
- {!! Form::select('tags[]', $tags, null, ['class' => 'form-control', 'multiple']) !!}
这次刷新页面,添加内容选择标签后再次提交,可以看到成功打印出了所有我们选择的标签,这正是我们需要的。
现在假设我们提交了表单,得到了标签数组,并且想把它们与这篇文章关联起来,前一节我们学习了使用
attach()
方法来实现该功能,看起来我们已经获得了所有我们需要的方法及数据,下面看看怎么做。
还有一点需要注意,我们使用
attach()
方法的时候,我们传递的参数是一个标签ID的数组,而上面我们得到的是标签名称的数组,所以还需要再次修改一下 create()
方法:
- public function create(){
- $tags = \App\Tag::lists('name', 'id');
- return view('articles.create', compact('tags'));
- }
然后刷新页面,添加内容选择标签后提交,可以看到打印出来的已经是标签对应的ID了。
接着,修改
store()
方法:
- public function store(ArticleRequest $request){
- $article = Auth::user()->articles()->create($request->all());
- $article->tags()->attach($request->input('tags'));
- flash()->overlay('文章发布成功', 'Good Job');
- return redirect('articles');
- }
这时,再次刷新页面,添加内容选择标签后发布,可以看到发布成功了,那么我们的标签是否添加成功了呢?可以使用数据库管理工具或者命令行工具
tinker
命令查看:
- //下面的 2 为刚刚发布的博客的ID
- >>> $article = \App\Article::find(2);
- => <App\Article #000000002ae45438000000003dea11ab> {
- id: 2,
- user_id: 1,
- title: "标题",
- body: "内容",
- created_at: "2015-08-02 01:02:03",
- updated_at: "2015-08-02 01:02:03",
- published_at: "2015-08-02 00:00:00",
- excerpt: null
- }
- >>> $article->tags->toArray();
- => [
- [
- "id" => 1,
- "name" => "PHP",
- "created_at" => "2015-07-25 21:29:45",
- "updated_at" => "2015-07-25 21:29:45",
- "pivot" => [
- "article_id" => 2,
- "tag_id" => 1,
- "created_at" => "2015-08-02 01:02:03",
- "updated_at" => "2015-08-02 01:02:03"
- ]
- ],
- [
- "id" => 4,
- "name" => "Python",
- "created_at" => "2015-08-02 00:35:53",
- "updated_at" => "2015-08-02 00:35:53",
- "pivot" => [
- "article_id" => 2,
- "tag_id" => 4,
- "created_at" => "2015-08-02 01:02:03",
- "updated_at" => "2015-08-02 01:02:03"
- ]
- ],
- [
- "id" => 5,
- "name" => "Go",
- "created_at" => "2015-08-02 00:36:01",
- "updated_at" => "2015-08-02 00:36:01",
- "pivot" => [
- "article_id" => 2,
- "tag_id" => 5,
- "created_at" => "2015-08-02 01:02:03",
- "updated_at" => "2015-08-02 01:02:03"
- ]
- ]
- ]
可以看到标签已经添加成功了。
三、在页面显示标签
修改 /resources/views/articles/show.blade.php 文件:
- @extends('main')
- @section('content')
{{ $article->title }}</h1>
- {{ $article->body }}</article>
Tags:</h5>
- @foreach($article->tags as $tag)
- {{ $tag->name }}</li>
- @endforeach
- </ul>
- @stop
现在到刚发布的文章的详情页,可以看到列出了所有添加的标签。但是如果打开一篇前面没有添加标签的博客详细页,可以看到下面多出了 “Tags:”,却没有标签,这不是我们想要的。我们需要当没有标签的时候,也不显示“Tags:”。
所以,接着修改刚才的 show.blade.php 文件:
- @extends('main')
- @section('content')
{{ $article->title }}</h1>
- {{ $article->body }}</article>
- @unless($article->tags->isEmpty())
Tags:</h5>
- @foreach($article->tags as $tag)
- {{ $tag->name }}</li>
- @endforeach
- </ul>
- @endunless
- @stop
这时打开没有标签的博客时,就不会显示出下面的“Tags:”了。
但是现在还有个问题,我们已经解决了添加标签的问题,而修改的时候却还没有做处理。这时打开一个博客的修改页会发现报错了。
修改 ArticlesController.php 中的
edit()
方法:
- public function edit(Article $article){
- $tags = \App\Tag::lists('name', 'id');
- return view('articles.edit', compact('article', 'tags'));
- }
现在刷新页面,可以看到已经列出了所有的标签,但是我们添加的标签并未选中,接着修改。
在 Article.php 中添加方法(用于获取博客中所有标签的ID):
- public function getTagListAttribute(){
- return $this->tags->lists('id');
- }
由于前面已经讲过了,修改页面用到了表单模型绑定,所以这里要修改 _form.blade.php 视图文件中标签的那一段:
class="form-group">- {!! Form::label('tag_list', 'Tags:') !!}
- {!! Form::select('tag_list[]', $tags, null, ['class' => 'form-control', 'multiple']) !!}
之后刷新页面,可以看到已经把我们添加的标签选中了。
Form::select()
方法的第二个参数为所有可选项,第三个参数为默认选中项,而由于Laravel的表单模型绑定,我们这里只需要把字段名字改为特定字段即可。对于表单模型绑定不记得的可以查看《 十三、子视图与表单重用》
由于上面我们改变了字段的名称,所有返回控制器文件,修改
store()
方法中相应的字段。
这时重新发布,查看,编辑一篇博客试试效果吧,但是还有一点,我们编辑文章保存的时候并没有对标签做处理,留待以后做。
该篇属于专题:《Laravel 5 基础视频教程学习笔记》
from : http://9iphp.com/web/laravel/laravel-5-select-tags-from-ui.html
沒有留言:
張貼留言