前回は多対多のリレーションの DB とモデルを実装し、tinker で動作確認を行いました。今回は記事の新規作成画面、編集画面から多対多のリレーションを扱いたいと思います。
Controller
ArticlesController.php を修正します。
<?php // app/Http/Controllers/ArticlesController.php namespace App\Http\Controllers; use App\Article; use App\Tag; use App\Http\Requests\ArticleRequest; class ArticlesController extends Controller { ... public function create() { $tag_list = Tag::pluck('name', 'id'); // ① return view('articles.create', compact('tag_list')); } public function store(ArticleRequest $request) { $article = Auth::user()->articles()->create($request->validated()); $article->tags()->attach($request->input('tags')); // ② return redirect()->route('articles.index') ->with('message', '記事を追加しました。'); } public function edit(Article $article) { $tag_list = Tag::pluck('name', 'id'); // ③ return view('articles.edit', compact('article', 'tag_list')); } public function update(Article $article, ArticleRequest $request) { $article->update($request->validated()); $article->tags()->sync($request->input('tags')); // ④ return redirect()->route('articles.show', [$article->id]) ->with('message', '記事を更新しました。'); } ... }
① create() と ③ edit()では、タグ名と id の一覧を View に渡すよう修正しました。
② store() では、リクエストで渡される tags を attach() メソッドで タグのリレーションに追加しています。
④ update() では、リクエストで渡される tags を sync() メソッドで タグのリレーションに同期しています。sync() メソッドでは article_tag テーブルのデータが引数で渡された id の物だけになるように、追加と削除を行います。
View
記事の新規作成、編集で使用しているフォームビューを修正します。
// resources/views/articles/form.blade.php ... <div class="form-group"> {!! Form::label('published_at', 'Publish On:') !!} {!! Form::input('date', 'published_at', $published_at, ['class' => 'form-control']) !!} </div> {{-- 追加 --}} <div class="form-group"> {!! Form::label('tags', 'Tags:') !!} {!! Form::select('tags[]', $tag_list, null, ['class' => 'form-control', 'multiple']) !!} </div> <div class="form-group"> {!! Form::submit($submitButton, ['class' => 'btn btn-primary form-control']) !!} </div>
select タグを追加しました。select タグは複数選択出来るようにする為、バインド名に括弧を付けて ‘tags[]’ とし、オプションに ‘multiple’ を入れます。
次に記事表示用のビューを修正します。
// resources/views/articles/show.blade.php @extends('layout') @section('content') <h1>{{ $article->title }}</h1> <hr/> <article> <div class="body">{{ $article->body }}</div> </article> {{-- 追加 --}} @unless ($article->tags->isEmpty()) <h5>Tags:</h5> <ul> @foreach($article->tags as $tag) <li>{{ $tag->name }}</li> @endforeach </ul> @endunless @auth <a href="{{ route('articles.edit', ['id' => $article->id]) }}" class="btn btn-primary" > 編集 </a> {!! delete_form(route('articles.destroy', ['id' => $article->id]), '削除') !!} @endauth @endsection
記事にタグがあれば、タグ一覧を表示するように修正しました。
これで、記事の新規作成、編集、表示でタグが扱えるようになりました。動作確認してみてください。
最後に
「はじめての Laravel 5.6」をご覧いただきありがとうございます。連載は今回で最終回となります。ブログの CRUD 機能を実装する演習を通して、Laravel の基本的な使い方は慣れることが出来たと思います。Laravel の魅力が伝わり、自分にも出来そうだと思っていただけたら幸いです。後は実際に開発を行い、問題に直面し、それを調べ、解決しながら進んで行きましょう。