2015.6.24
0からはじめるPHP#28【Laravel5で作るデータベース#2-データベース内容の一覧表示-】
前回データベースのデータ取得をしましたが、今回はそのデータをビューに渡したいと思います。
まぁこれは結構簡単です。
public function index()
{
$tests = DB::table('tests')->get();
return view('viewname')->with('tests',$tests);
}
前回と違うのは4行目です。やっぱあの書き方はマズかったらしく、ちゃんとwithで指定しないと動かないっぽいです。
マニュアルにはイケるって書いてあったんだけどなぁ。
あ、前回触れてませんでしたが、データベースの設定はちゃんとしないと当然動かないです。
Laravel5では、データベース設定は
.envという謎のファイルから変数を設定できます。これなんの略なんですかね。environmentですかね。
<!DOCTYPE HTML>
<html>
<head>
タイトル
</head>
<body>
@yield('content')
</body>
</html>
@extends('layout')
@section('content')
<table>
<tr>
<th>曲名
<th>副題
<th>作品番号
<th>時間
</tr>
@foreach($test as $tests)
<tr>
<td>{{$test->title}}
<td>{{$test->subtitle}}
<td>{{$test->number}}
<td>{{$test->time}}
</tr>
@endforeach
</table>
@endsection
viewnameに関しては各自で好きな名前にしてもらったらいいと思うんですが、具体的な使い方はこんな感じです。後はカラム数に合わせてテーブルを作れば全件表示ができます。
まぁ、さすがにHTMLの知識もなしにPHPやる人はいないと思うのでこの辺はスルーで。foreachの使い方もPHPのそれと一緒です。
この例ではビューを2つに分けてますが、もちろん単一のものでも大丈夫です。ただ、2つに分けた方が見栄えがすっきりしますし、フレームワークの利点を活かせてるので基本的にこのように使ったほうがいいかなと思います。
解説ですね。ではまずlayoutファイルから。
これは見たら分かる通り、HTMLの骨組みを書いています。
で、
@yieldの部分に埋め込んでいく形になります。
で、その中に埋め込む内容がviewname.blade.phpです。
1行目のextendsで、先ほどのlayoutファイルを読み込んでいます。
で、その次のsectionですが、layoutと同じく"content"という文字列が指定されてますよね。まぁ、見て分かると思うんですが、ここで対応してます。
@endsectionまでがcontent部に挿入されるわけですね。非常に分かりやすいですね。正直解説は要らないと思います。(笑)
ただ、気をつけたいのは、foreachにもアットマークがつくことぐらいですかね。
あと、変数の参照は二重括弧でくくってやらなければなりません。
これで全件表示ができました。
ここで、一歩進んだことをやってみましょう。
正規化されたデータベースの取り扱いです。
データベースの正規化ってのは、まぁ調べたらでてくるんですけど
データベースの分割です。
例えば、名簿をデータベース化するとしましょう。カラムは
名前|年齢|都道府県だとしましょう。
| 名前(主キー) | 年齢 | 都道府県 |
| A | 10 | 北海道 |
| B | 3 | 鳥取県 |
| C | 30 | 大阪府 |
| D | 27 | 東京都 |
| E | 85 | 大阪府 |
| F | 1 | 東京都 |
こーいうデータベースがあったとします。
ここで
大阪都構想が実現し、唐突に大阪都が出現したと仮定しましょう。
※余談ですが、仮に大阪都構想が実現していたとしても大阪府という名前は変わらなかったようです。
大阪都構想に関しては先ほど軽く調べてみたんですが、これ否決されたのすごい残念ですよね。明らかに無駄やん・・・・・・。
まぁ、こういった変化が現れた時、大阪府という場所を大阪府、に書き換えるのが普通の発想です。
が、データベースの分野に於いては
これはやってはならない設計です。
正しくはこうです。
名簿テーブル
| 名前(主キー) | 年齢 | 都道府県ID(外部キー) |
| A | 10 | 1 |
| B | 3 | 2 |
| C | 30 | 3 |
| D | 27 | 4 |
| E | 85 | 3 |
| F | 1 | 4 |
都道府県テーブル
| 都道府県ID(主キー) | 都道府県 |
| 1 | 北海道 |
| 2 | 鳥取県 |
| 3 | 大阪府 |
| 4 | 東京都 |
これを正規化といっていいのか正直よくわからないんですが、こうすると何がメリットか分かりますか?
この例であれば、大阪府という名称を変更しようと思えば
都道府県テーブルの該当箇所のみ変更すれば良いということになるんですよ。
つまり、変更する可能性があり、かつ何度も同じものがでてきくる場合はこのように分割して設計しなければいけないんですよね。
もちろん、やりすぎると逆に管理がし辛くなるというデメリットもあったりするのですが、この場合分割しない理由はないです。
今回サンプル・・・・・・というか、僕の練習用に作っているデータベースも例に漏れずこのように正規化されています。
ただ、正規化されたデータベースはきちんと連結させないと意味ないですよね。当然。
ということで、その連結作業をやってみましょう。
データベースの連結はどのようにしたらいいかを考えてみましょう。
まぁ、普通に考えたら、例えば上の例でいえば、名簿デーブルを読み込んで、都道府県IDを読み取る時に条件分岐して、都道府県テーブルから値を読み込む・・・・・・ということを連想すると思うんですよね。僕はそうでした。(笑)
ただ、データベースにはそれを自動でやってくれる命令があります。
JOINです。
JOINに関してはまぁ、色々あるんで調べて下さいって感じなんですけど、やりたいことは
正規化したテーブルを元に戻すという作業です。
つまり、上の例でいうと、名簿テーブルに都道府県テーブルをくっつけたいわけです。
一口にJOINといっても、内部結合とか外部結合とか、まぁ色々あるんで、結合した後の形をイメージして、どの形がいいかを決めていくわけですが、まぁ上の例だと内部結合がしっくりきますよね。
名簿テーブル+都道府県テーブル
| 名前(主キー) | 年齢 | 都道府県ID | 都道府県 |
| A | 10 | 1 | 北海道 |
| B | 3 | 2 | 鳥取県 |
| C | 30 | 3 | 大阪府 |
| D | 27 | 4 | 東京都 |
| E | 85 | 3 | 大阪府 |
| F | 1 | 4 | 東京都 |
つまり、こういうのを目指す時は名簿テーブルに都道府県テーブルを内部結合させましょう、って話です。
実際は都道府県IDのカラムはダブって2つになるようですが
(NATURAL JOINというもので解決します)プログラムの配列表現上ではあんま気にしなくても良いと思います。
さて、こういったことをLaravel5ではどのようにするのかというと、このように表現します。
$results=DB::table('compositions')
->leftJoin('composers','composers.composer_id','=','compositions.composer_id')
->leftJoin('genres','genres.genre_id','=','compositions.genre_id')
->leftJoin('tonalities','tonalities.tonality_id','=','compositions.tonality_id')
//->leftJoin('countries','countries.country_id','=','composers.country_id')
->get();
return view('index')->with('compositions',$results);
※コメントアウトした一行は次回解説します。
段々めんどくさくなってきたので、僕が今開発してるデータベースの名前そのまんまです。たぶん大丈夫でしょ。(笑)
さきほどJOIN命令にはいろいろあるって言いましたが、そのうちの一つである
LEFT JOINという命令と同等の命令がLaravelのクエリービルダーにあるので、こちらを使います。
|
->leftJoin('結合したいテーブル名','参照したいテーブル名.カラム名','計算式','参照したいテーブル名2.カラム名')
|
日本語で書くとややこしいですが、上の例でいうと、まず最初にcompositions(作品データ)というテーブルを読み込みます。これに色々くっつけたいわけですね。
次に二行目にcomposers(作曲家データ)というテーブルをJOINしたいと思っています。
compositionsテーブルと、composersテーブルには
ともに"composer_id"というカラムを持っています。これが前提です。先ほどの例と一緒ですね。
で、二行目のleftJoinの意味は、日本語で言うと
composersのcomposer_idとcompositionsのcomposer_idが等しいものを結合して下さいって意味になります。
まぁこれで、composer_idに対応した、composersテーブルのcomposerカラムの値がくっついてくるわけですね。
よくわかんなかったらコントローラの方でvar_dumpしてみてください。ビューでは使えませんけどコントローラではちゃんとダンプできて内部構造が見えます。見たらわかります。(笑)
で、同様のことを三行目、四行目ってやっていって、最終的にできたものをビューに渡しているんですね。
|
view('ビューの名前')->with('ビューでの変数名',渡したい変数)
|
複数の変数を渡したかったら、->with()->with()->...って続けたらいいみたいです。
上の例だと、resultって変数をcompositionsって変数名で参照できるように渡しているんですね。
ビューに関しては次回やる予定です。そろそろフレームワークの恩恵が受けられるようになってきました。(笑)
先輩がデータベースに使うデータを作ってくれたんで、なんかすげーやる気出てきたんですよね。(笑)
とりあえずさっさとこいつを完成させて、僕はオケに貢献する偉大な先輩になりたいと思います←