前回(第2回目 -登録(テーブル/モデル作成)編-)に引き続き、
今回はICOのwebアプリに含まれる
登録とタグ機能をコントローラを使用しながら作成していきます。
ルーティングとモデルは前回作成し終えたので、
次にコントローラを作っていきます。
コントローラ
1 |
$ php artisan make:controller IcosController |
app/Http/controllers 直下にIcosController.phpが生成されます。

1 |
$ico = new Ico; |
1 2 3 |
return view('icos.create', [ 'ico' => $ico, ]); |
フォームを表示するという処理です。
ビュー(ICO登録フォーム画面)
それでは、ICO登録フォーム画面の表示先である
icos/create.blade.phpで見た目を作成していきます。
icos/create.blade.php内に以下のようにフォームを記述します。



1 2 3 4 5 6 |
<head> <!-- Bootstrap--> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> <!--style.css--> <link rel="stylesheet" href="/css/style.css"> </head> |

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<head> <!-- Bootstrap--> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> <!--style.css--> <link rel="stylesheet" href="/css/style.css"> </head> <h1>ICO登録</h1> <div class="col-md-6 col-md-offset-3"> {!! Form::model($ico, ['route' => 'icos.store']) !!} <div class="form-group"> {!! Form::label('title', '仮想通貨名') !!} {!! Form::text('title',null, ['class' => 'form-control']) !!}<br/> </div> <div class="form-group"> {!! Form::label('description', '内容') !!} {!! Form::textarea('description',null, ['class' => 'form-control', 'rows' => '3']) !!}<br/> </div> <div class="form-group"> {!! Form::label('url', 'URL') !!} {!! Form::text('url', null,['class' => 'form-control', 'rows' => '3']) !!}<br/> </div> <div class="form-group"> {!! Form::label('name', 'タグ') !!} {!! Form::text('name',null, ['class' => 'form-control', 'rows' => '3']) !!}<br/> </div> <div class="form-group"> <label>アップロード</label> <input type="file" name="file" id="file"> <input type="hidden" value="{{ csrf_token() }}" name="_token"> </div> {!! Form::submit('登録', ['class' => 'btn btn-lg btn-primary']) !!} {!! Form::close() !!} </div> |

タグ機能
tags | id |
name |
1 |
$ php artisan make:migration create_tags_table --create=tags |
1 2 3 4 5 |
Schema::create('tags', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->timestamps(); }); |
1 |
$ php artisan migrate |
その次に、
1 |
$ php artisan make:migration create_ico_tag_table --create=ico_tag |
1 2 3 4 5 6 7 8 9 10 11 12 |
public function up() { Schema::create('ico_tag', function (Blueprint $table) { $table->increments('id'); $table->integer('tag_id')->unsigned(); $table->integer('ico_id')->unsigned(); $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade'); $table->foreign('ico_id')->references('id')->on('icos')->onDelete('cascade'); $table->primary(['tag_id', 'ico_id']); $table->timestamps(); }); } |
あとは
1 |
$ php artisan migrate |
でマイグレーションを実行するだけです。
モデル
1 2 3 4 |
public function tags() { return $this->belongsToMany('App\Tag'); } |
その次に、
1 |
$ php artisan make:model Tag |
でTagモデルを作成します。
1 2 3 4 5 6 7 8 9 |
class Tag extends Model { protected $fillable = ['name']; public function icos() { return $this->belongsToMany('App\Ico'); } } |
ルーティング
1 2 |
//タグ Route::get('/tags/{id}/icos', 'IcosController@showByTag')->name('tags.icos'); |
コントローラで登録画面で入力したデータの保存・表示・タグ機能を実行します。
コントローラ
app/Http/Controllers/IcosController.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Requests; use App\Http\Controllers\Controller; use App\Ico; use App\Tag; class IcosController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { $icos = Ico::all(); return view('icos.index', [ 'icos' => $icos, ]); } /** * Show the form for creating a new resource. * * @return \Illuminate\Http\Response */ public function create() { $ico = new Ico; return view('icos.create', [ 'ico' => $ico, ]); } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { $this->validate($request, [ 'title' => ['required', 'string', 'max:45'], ]); $ico = new Ico; $ico->title = $request->title; $ico->description = $request->description; $ico->url = $request->url; $ico->save(); // タグ保存 // ex: preg_split('/\s+/', ' tag1 tag2 tag3 tag4 ', -1, PREG_SPLIT_NO_EMPTY) // == ['tag1', 'tag2, 'tag3', 'tag4']; $tag_names = preg_split('/\s+/', $request->name, -1, PREG_SPLIT_NO_EMPTY); $tag_ids = []; foreach ($tag_names as $tag_name) { $tag = Tag::firstOrCreate([ 'name' => $tag_name, ]); $tag_ids[] = $tag->id; } // 中間テーブル $ico->Tags()->sync($tag_ids); $request->session()->flash('flash_message', '登録完了!'); return redirect()->route('icos.index'); } /** * Display the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function show($id) { // } /** * Show the form for editing the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function edit($id) { // } /** * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request * @param int $id * @return \Illuminate\Http\Response */ public function update(Request $request, $id) { // } /** * Remove the specified resource from storage. * * @param int $id * @return \Illuminate\Http\Response */ public function destroy($id) { // } public function showByTag($id){ $tag = Tag::find($id); return view('icos.index', [ 'icos' => $tag->icos, ]); } } |
ビュー(ICO登録内容の一覧表示画面)
ICO登録画面で保存した内容を表示するicos/index.blade.phpは以下のように記述します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
<h1>ICO一覧</h1> <div class="row"> <div class="col-md-2"> <a class="btn btn-primary" href="{{ route('icos.create') }}">ICO新規登録</a> </div> <div class="col-md-10"> @if(Session::has('flash_message')) <div class="alert alert-success"> {{ Session::get('flash_message') }} </div> @endif <table class="table"> <tbody> @foreach($icos as $ico) <tr> <td> <ul class="list-unstyled"> <li> {{ $ico->title }} {{ $ico->description }} {{ $ico->url }} </li> @if(count($ico->Tags) > 0) <li> <ul class="list-inline"> @foreach($ico->Tags as $tag) <li> <a href="{{ route('tags.icos', ['id' => $tag->id]) }}"> <span class="label label-info"> <span class="glyphicon glyphicon-tags" aria-hidden="true"></span> {{ $tag->name }} </span> </a> </li> @endforeach </ul> </li> @endif </ul> </td> </tr> @endforeach </tbody> </table> </div> </div> |
これで動作確認をしてみます。
※タグはスペースでキーワードの区切りを認識しています
上のようにICO登録画面であるcreate.blade.php内のフォームに入力したら、
「登録」ボタンを押してみます。
すると、コントローラのstoreで記述したように、
index.blade.phpにつながり、
入力した内容が表示されていたので、
データ表示は成功しているみたいです。
タグもリンク文字列としてしっかり表示されています。
あとはタグを押すと、そのタグに関連した内容のデータのみが
表示されるようになるかを確認しなければなりません。
上の中の「赤」タグを押してみます。
「赤」というタグを登録しているデータのみ表示することができました。
タグ機能も成功しているようです。
あとは登録内容の中に画像もあるので、
次回はどのように画像を保存し、表示させるかについて触れたいと思います。
参考:PHPフレームワーク(Laravel)を使った効率的なWebアプリケーション開発