[Laravel 5] 筆記17 Selecting Tags From the UI, Syncing Tags

2015-03-17

https://laracasts.com/series/laravel-5-fundamentals/episodes/22
https://laracasts.com/series/laravel-5-fundamentals/episodes/23

這節介紹怎麼在新增編輯表單中增加 tags 的選項
首先是修改 controller
▼ app/Http/Controllers/ArticlesController.php

    public function create()
    {
        // 取得目前有的 tags
        // lists() 第一個參數是欄位名稱 第二個參數是可選的 可以指定給出的 array 的 key 值要用哪個欄位
        // 這邊是用 id 才能讓 view 的 select 使用
        $tags = \App\Tag::lists('name','id');

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

    public function store(ArticleRequest $request)
    {
        // 取得 $article 以供後一行使用
        //$article = \Auth::user()->articles()->create($request->all());

        // 使用前一節說明的 attach() 可以放單一個值 或是放一個 array
        //$article->tags()->attach($request->input('tag_list'));

        // 將上面這兩行再寫成一個 private method
        $this->createArticle($request);

        return redirect('articles')->with([
            'flash_message' => '新增成功 [with] !!'
        ]);
    }

    public function edit(Article $article)
    {
        // 同 create()
        $tags = \App\Tag::lists('name','id');
        return view('articles.edit', compact('article','tags'));
        
    }

    public function update(Article $article, ArticleRequest $request)
    {
        $article->update($request->all());

        // attach() 是新增用, detach() 是刪除用, sync() 是同步用
        // 這邊使用 sync() 來簡化更新時候要做的處理
        //$article->tags()->sync($request->input('tag_list'));
        
        // 將上面那行寫成一個 private method
        $this->syncTags($article, $request->input('tag_list'));
        
        return redirect('articles');
    }

/* 以下是新增的兩個 private method */

    private function createArticle(ArticleRequest $request)
    {
        $article = \Auth::user()->articles()->create($request->all());

        // 這邊也改成共用的 private method
        $this->syncTags($article, $request->input('tag_list'));
        
        return $article;
    }

    private function syncTags(Article $article, Array $tags)
    {
        $article->tags()->sync($tags);
    }

 
接著在 model Article.php 加上一個取得這 article 所有 tags 的 method
▼ app/Article.php

    // 不能使用 getTagsAttribute() 因為會蓋到內建的 method
    public function getTagListAttribute()
    {
        return $this->tags()->lists('id');
    }

 
接著在 form.blade.php 這個 form partial 加上 select
▼ resource/views/articles/form.blade.php


    
{!! Form::label('tag_list', 'Tags:') !!} {!! Form::select('tag_list[]', $tags, null, ['class' => 'form-control', 'multiple']) !!}

 
最後在 show.blade.php 顯示 tags
▼ resource/views/articles/show.blade.php

    
    @unless($article->tags->isEmpty())
    
Tags:
    @foreach ($article->tags->lists('name') as $tag)
  • {{ $tag }}
  • @endforeach
@endunless