速習Larave3(その14)、タグNo.2

タグ: Laravel3  

タグを導入しましょう。前回は多:多の関係の前準備の知識を学習し、テーブルを作成しました。

では、コードを見て行きましょう。

Postコントローラーです。変更部分のみ示しますので、該当部分を変更してください。

    /**
     * 記事表示
     */
    public function get_show($id)
    {
        $post = Post::with(array('comments', 'comments.user'))->find($id);

        if ( $post === null )
        {
            return Redirect::error('404');
        }

        $tags = Tag::get_by_string($id);

        return View::make('post.show')
                ->with('post', $post)
                ->with('tags', $tags);
    }

    /**
     * 記事追加/編集フォーム表示
     */
    public function get_edit($id = null)
    {
        // フラッシュデーターとしてセッションに
        // 保存されている入力を取得
        $inputs = array_only(
            Input::old(), array( 'title', 'body', 'tags' ));

        // フラッシュデータが存在しない場合
        // フォーム処理からのリダイレクトではなく
        // 初めて呼び出されたということ
        if ( empty($inputs) )
        {
            // 初回処理

            if ( $id === null )
            {
                // 新規記事追加
                $data = array(
                    // ページ出力は空文字列
                    'title' => '',
                    'body' => '',
                    'tags' => '',
                );
            }
            else
            {
                // 更新処理
                $post = Post::find($id);

                if ( $post === null )
                {
                    return Redirect::error('404');
                }

                $data = array(
                    // ページ出力は既存のレコード
                    'title' => $post->title,
                    'body' => $post->body,
                    'tags' => Tag::get_by_string($id),
                );
            }
        }
        else
        {
            // フォーム更新時
            $data = array(
                // ページ出力はフォームの入力データー
                'title' => $inputs['title'],
                'body' => $inputs['body'],
                'tags' => $inputs['tags'],
            );
        }
        return view('post.form')
                ->with('title', $data['title'])
                ->with('body', $data['body'])
                ->with('tags', $data['tags']);
    }

    /**
     * 記事追加フォーム処理
     */
    public function post_edit($id = null)
    {
        // バリディーションルール
        $rules = array(
            'title' => 'required|max:50',
            'body' => 'required|max:8000',
        );

        $input = Input::only(array( 'title', 'body', 'tags' ));

        $val = Validator::make($input, $rules);

        if ( $val->passes() )
        {
            // バリデーション通過
            if ( $id === null )
            {
                // 新ポストの追加
                $post = new Post(array_only($input, array( 'title', 'body' )));
                $post->save();

                // 入力タグの処理
                if ( ! Tag::put_by_string($post->id, $input['tags']) )
                {
                    return Redirect::error('500');
                }

                // 続けて投稿しやすいように
                // 再度追加処理へ(IDを付けないでリダイレクト)
                return Redirect::to_route('post-edit')
                        ->with('message', '記事を投稿しました。');
            }
            else
            {
                // 既存ポストの更新
                $post = Post::find($id);

                if ( $post === null )
                {
                    return Redirect::error('404');
                }

                $post->title = $input['title'];
                $post->body = $input['body'];
                $post->save();

                // 入力タグの処理
                if ( ! Tag::put_by_string($id, $input['tags']) )
                {
                    return Redirect::error('500');
                }

                // 同じ記事を修正しやすいように
                // 再度記事を表示させる
                return Redirect::to_route('post-edit', array( $id ))
                        ->with_input()
                        ->with('message', '記事を編集しました。');
                // with_input()が無くても同じ記事が表示されるが
                // よけいなDBアクセスをさせない
            }
        }
        else
        {
            // バリデーション失敗
            return Redirect::to_route('post-edit', array( $id ))
                    ->with_input()
                    ->with_errors($val);
        }
    }

記事の表示ビューでタグ表示を追加です。追加/更新フォームでもタグを取り扱うように修正しました。

追加/更新フォームform.blade.phpの適当な場所に、以下のコードを追加してください。タグの入力エリアです。

        <div>
            {{ Form::label('tags', 'タグ') }}<br>
            {{ Form::text('tags', $tags) }}
            @if ($errors->has('tags'))
                <p style="color: red;">{{ $errors->first('tags') }}</p>
            @endif
        </div>

記事の表示ビューshow.blade.phpにタグ表示のコードを入れてください。

    <div>
        <h5>タグ:</h5>
        <p>{{ e($tags) }}</p>
    </div>

モデルを見てみましょう。まずは既存のPostモデルに、多:多関係をコーディングします。

<?php

class Post extends Eloquent
{
    public static $timestamps = true;

    public function comments()
    {
        return $this->has_many('Comment');
    }

    public function tags()
    {
        return $this->has_many_and_belongs_to('Tag');
    }
}

残りは新しく作成したtagsテーブルのEloquentモデル、tags.phpです。これは長くなり、解説が必要ですので、次の記事でお読みください。