初めてのLaravel 5.1 : (34) 多対多のリレーション UI編

前回は多対多のリレーションのDBとモデルを実装し、tinkerで動作確認を行いました。今回は記事の新規作成画面、編集画面から多対多のリレーションを扱いたいと思います。


Model

Tagの idの配列が取得できるよう、Article.php を修正します。

<?php // app/Article.php
namespace App;

...

class Article extends Model {
	...

	public function tags() {
		return $this->belongsToMany('App\Tag')->withTimestamps();
	}

	// 追加
	public function getTagListAttribute() {
		return $this->tags->lists('id')->all();
	}
}

getTagListAttribute()アクセッサを追加することで、$article->tag_list() で tagの id の配列が取得できるようにします。


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() {
		$tags = Tag::lists('name', 'id');  // ①

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

	public function store(ArticleRequest $request) {
		$article = \Auth::user()->articles()->create($request->all());
		$article->tags()->attach($request->input('tag_list'));  // ②

		\Session::flash('flash_message', '記事を追加しました。');

		return redirect()->route('articles.index');
	}

	public function edit(Article $article) {
		$tags = Tag::lists('name', 'id');  // ③

		return view('articles.edit', compact('article', 'tags'));
	}

	public function update(Article $article, ArticleRequest $request) {
		$article->update($request->all());
		$article->tags()->sync($request->input('tag_list', []));  // ④

		\Session::flash('flash_message', '記事を更新しました。');

		return redirect()->route('articles.show', [$article->id]);
	}

	...

}

①create()と③edit()では、タグ名と idの一覧をViewに渡すよう修正しました。

②store()では、リクエストで渡される tag_list を attach()メソッドで タグのリレーションに追加しています。

④update()では、リクエストで渡される tag_list を sync() メソッドで タグのリレーションに同期しています。sync()メソッドでは中間テーブルのデータが引数で渡された 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('tag_list', 'Tags:') !!}
	{!! Form::select('tag_list[]', $tags, null, ['class' => 'form-control', 'multiple']) !!}
</div>

<div class="form-group">
	{!! Form::submit($submitButton, ['class' => 'btn btn-primary form-control']) !!}
</div>

selectタグを追加しました。先ほどArticleモデルに、getTagListAttribute()を追加したので、’tag_list’という属性名でFromと$articleをバインドできます。selectタグは複数選択出来るようにする為、バインド名に括弧を付けて ‘tag_list[]’ とし、オプションに ‘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

	@if (Auth::check())
		<br/>

		{!! link_to(route('articles.edit', [$article->id]), '編集', ['class' => 'btn btn-primary']) !!}

		<br/>
		<br/>

		{!! delete_form(['articles', $article->id]) !!}
	@endif
@stop

記事にタグがあれば、タグ一覧を表示するように修正しました。

これで、記事の新規作成、編集、表示でタグが扱えるようになりました。動作確認してみてください。


最後に

「はじめての Laravel 5.1」の連載は今回で最終回となります。ブログのCRUD機能を実装する演習を通して、Laravel 5.1 の基本的な所は慣れることが出来たと思います。後は実際に開発を行い、問題に直面し、それを調べ、解決しながら進んで行きましょう。

今後は不定期にはなりますが、Laravel に関するブログは継続して行きます。

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中