Webアプリを自作するためにPHPのフレームワークのLaravelを導入することに決めました。
PHP初心者かつLaravel初心者ですが、自分なりにスキルを得るためにLaravelを用いた記事投稿アプリを自作しました。その過程を備忘録としてまとめます。
最終的にはブラウザを利用して記事投稿画面の表示、ユーザごとの記事投稿数のグラフ化を目指したいと思います。
本記事は連載【投稿アプリ自作】の第七回目で、前回作成したダミーデータの取得と表示する方法をまとめます。
※:Laravelは5.3からファイル構成が大幅に変わりました。本記事ではLaravel5.3以降を使って説明したいと思います。
※2:データベースはXAMPPに入っていたMySQLを使うことにします。事前にデータベースアカウントを登録しておいてください。
目次
目次
- 1 目次
- 2 ゴール
- 3 必要なもの
- 4 事前準備
- 5 Laravelソースファイルの変更
- 6 ブラウザで確認
- 7 まとめ
ゴール
本記事では、以下の2つについてまとめます。
・hasMany()やbelongsTo()関数を使ってリレーションの定義
・入手した情報を画面に表示
以下の画像には前回(第6回目)で作成したダミーデータを使って記事IDごとに各データが格納されているデータベースからデータを入手して、記事の内容を表示したものになります。
本記事ではこのようにデータベース間でのデータの入手ができるようにする方法をまとめます。
必要なもの
必要なもの | 価格(円) | ||
---|---|---|---|
1 | PC | ピンキリ | |
備考 | インターネット接続可能なこと | ||
2 | XAMPP | 無料 | |
備考 | 持っていない場合は、こちらを参照→XAMPPのインストール方法 | ||
3 | Laravelフレームワーク | 無料 | |
備考 | インストールしていない場合は、こちらを参照→Laravelのインストール方法 | ||
4 | MySQLのデータベースアカウント | 無料 | |
備考 | 持っていない場合は、こちらを参照→phpMyAdminでデータベースとユーザを新規登録する | ||
5 | 投稿アプリ向けのテーブル | 無料 | |
備考 | 【投稿アプリ自作】の第四回目で作成した投稿アプリ向けのテーブルです。持っていない場合は、こちらを参照→【投稿アプリ自作(4)】テーブル設計とマイグレーション実行(Laravel) | ||
6 | ダミーデータ | 無料 | |
備考 | 【投稿アプリ自作】の第六回目で作成した投稿アプリ向けのダミーデータです。持っていない場合は、こちらを参照→【投稿アプリ自作(6)】seederでダミーデータの作成(Laravel) |
事前準備
テーブルの作成
事前に投稿アプリ向けのテーブルを用意する必要があります。
第四回目でテーブル設計と新規テーブルの作成方法をまとめていますので、まだ作成していない方は以下の記事を参考にして新規テーブルの作成をしてください。
テーブルの関連性
投稿アプリ向けのテーブルの関連性をER図にまとめると下の様になります。(IDEDF1X記法で記述)
※ネットで検索しながら見よう見まねで書いたので間違っているかもしれませんがご容赦ください。
ダミーデータの作成
本記事でアクセスするためのダミーデータが必要です。
前回の記事でダミーデータの作成方法をまとめていますので、ダミーデータがない場合は以下の記事を参考にダミーデータの作成をしてください。
Laravelソースファイルの変更
変更や新規作成するLaravelファイル一覧
Laravelのプロジェクトファイル配下にあるファイルで本記事の中で変更、新規作成するファイルについてまとめました。
ファイル名 | 対応 | 備考 | |
---|---|---|---|
1 | app/Article.php | 変更 | |
2 | app/ArticleUser.php | 変更 | |
3 | app/Category.php | 変更 | |
4 | app/DetailedArticle.php | 変更 | |
5 | app/Tag.php | 変更 | |
6 | app/Http/Contoroller/ArticleController.php | 変更 | |
7 | routes/web.php | 変更 | |
8 | resources/views/test/test1.blade.php | 新規作成 | |
9 | resources/views/test/test2.blade.php | 新規作成 |
リレーション定義に使用するメソッドの紹介
以下ではそれぞれのモデルファイルにリレーションの定義をしますが、その前にそもそもリレーション定義に使用するメソッドをまとめたいと思います。
1対1リレーション
1対1関係のテーブルを紐づけるために使用する関数です。
メソッド名 | 備考 | |
---|---|---|
1 | hasOne(string $related, string $foreignKey = null, string $localKey = null) | APIリファレンス |
2 | belongsTo(string $related, string $foreignKey = null, string $ownerKey = null, string $relation = null) | APIリファレンス |
今回の記事では1対1の関係になっているのは「ArticlesテーブルとDetailedArticlesテーブル」の関係になります。
それぞれの関係は以下の様になっており、article_idで1対1に紐づいています。
[Articlesテーブル]
・記事ID :article_id(主キー)
・その他カラム
[DetailedArticleテーブル]
・記事ID :article_id(主キー)
・その他カラム
1対1リレーション定義 hasOne
このとき、DetailedArticleテーブル->Articlesテーブルへのリレーションを定義すると以下の様になります。
1 2 3 |
public function articles(){ return $this->hasOne('App\Article','article_id'); } |
1対1リレーション アクセス方法
アクセスするときは以下の様に使用します。
1 |
$article = DetailedArticle::find(1)->articles; |
1対1リレーション定義 belongsTo
逆にArticlesテーブル->DetailedArticleテーブルへのリレーションを定義すると以下の様になります。
1 2 3 |
public function detailedArticle(){ return $this->belongsTo('App\DetailedArticle','article_id'); } |
1対1リレーション アクセス方法
アクセスするときは以下の様に使用します。
1 |
$detailedArticle = Article::find(1)->detailedArticle; |
1対多リレーション
1対多関係のテーブルを紐づけるために使用する関数です。
メソッド名 | 備考 | |
---|---|---|
1 | hasMany(string $related, string $foreignKey = null, string $localKey = null) | APIリファレンス |
2 | belongsTo(string $related, string $foreignKey = null, string $ownerKey = null, string $relation = null) | APIリファレンス |
今回の記事では1対多の関係になっているのは「ArticleUsersテーブルとArticlesテーブル」や「CatergoriesテーブルとArticlesテーブル」、「TagsテーブルとArticlesテーブル」の関係になります。
例として「ArticleUsersテーブルとArticlesテーブル」を上げると、それぞれの関係は以下の様になっており、user_idで1対多に紐づいています。
[ArticleUsersテーブル]
・ユーザID :user_id(主キー)
・その他カラム
[Articlesテーブル]
・記事ID :article_id(主キー)
・ユーザID :user_id(外部キー)
・その他カラム
1対多リレーション定義 hasMany
このとき、ArticleUsersテーブル->Articlesテーブルへのリレーションを定義すると以下の様になります。
1 2 3 |
public function articles(){ return $this->hasMany('App\Article','user_id'); } |
1対多リレーション アクセス方法
アクセスするときは以下の様に使用します。
1 |
$article = ArticleUser::find(1)->articles; |
1対多リレーション定義 belongsTo
逆にArticlesテーブル->ArticleUsersテーブルへのリレーションを定義すると以下の様になります。
1 2 3 |
public function articleUser(){ return $this->belongsTo('App\ArticleUser','user_id'); } |
1対多リレーション アクセス方法
アクセスするときは以下の様に使用します。
1 |
$articleUser = Article::find(1)->articleUser; |
Articlesテーブルのモデルファイルの変更
Articlesテーブルのモデルファイルに対してリレーションを定義します。
Articlesテーブルには以下のようなリレーショナルになっています。
・ArticleUsersテーブルとuser_idで多対1
・Categoriesテーブルとcategory_idで多対1
・Tagsテーブルとtag_idで多対1
・DetailedArticlesテーブルとarticle_idで1対1
(詳しくはテーブルの関連性の章を見てください。)
上記内容をモデルファイルに変更を加えると以下の様になります。
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 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Article extends Model { protected $table = 'articles'; protected $primaryKey = "article_id"; public function articleUser(){ return $this->belongsTo('App\ArticleUser','user_id'); } public function category(){ return $this->belongsTo('App\Category','category_id'); } public function tag(){ return $this->belongsTo('App\Tag','tag_id'); } public function detailedArticle(){ return $this->belongsTo('App\DetailedArticle','article_id'); } } |
ArticleUsersテーブルのモデルファイルの変更
ArticleUsersテーブルのモデルファイルに対してリレーションを定義します。
ArticleUsersテーブルには以下のようなリレーショナルになっています。
・Articlesテーブルとuser_idで1対多
(詳しくはテーブルの関連性の章を見てください。)
上記内容をモデルファイルに変更を加えると以下の様になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class ArticleUser extends Model { protected $table = 'article_users'; protected $primaryKey = "user_id"; public function articles(){ return $this->hasMany('App\Article','user_id'); } } |
Categoriesテーブルのモデルファイルの変更
Categoriesテーブルのモデルファイルに対してリレーションを定義します。
Categoriesテーブルには以下のようなリレーショナルになっています。
・Categoriesテーブルとcategory_idで1対多
(詳しくはテーブルの関連性の章を見てください。)
上記内容をモデルファイルに変更を加えると以下の様になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Category extends Model { protected $table = 'categories'; protected $primaryKey = "category_id"; public function articles(){ return $this->hasMany('App\Article','category_id'); } } |
DetailedArticlesテーブルのモデルファイルの変更
DetailedArticlesテーブルのモデルファイルに対してリレーションを定義します。
DetailedArticlesテーブルには以下のようなリレーショナルになっています。
・Articlesテーブルとarticle_idで1対1
(詳しくはテーブルの関連性の章を見てください。)
上記内容をモデルファイルに変更を加えると以下の様になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class DetailedArticle extends Model { protected $table = 'detailed_articles'; protected $primaryKey = "article_id"; public function articles(){ return $this->hasOne('App\Article','article_id'); } } |
Tagsテーブルのモデルファイルの変更
Tagsテーブルのモデルファイルに対してリレーションを定義します。
Tagsテーブルには以下のようなリレーショナルになっています。
・Articlesテーブルとtag_idで1対多
(詳しくはテーブルの関連性の章を見てください。)
上記内容をモデルファイルに変更を加えると以下の様になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Tag extends Model { protected $table = 'tags'; protected $primaryKey = "tag_id"; public function articles(){ return $this->hasMany('App\Article','tag_id'); } } |
これでモデルファイルの変更ができたので、次にコントローラとビューを変更・新規作成します。
ArticleControllerの変更
[変更点]
・その1
hasManyを確認するためにtest1ビューファイルを作成します。
そのため、test_hasMany_user2article()関数を作成します。
内容は、ArticleUserテーブルのデータをtest1ビューにリターンします。
・その2
belongsToを確認するためにtest2ビューファイルを作成します。
そのため、test_belongsTo_article2user()関数を作成します。
内容は、Articleテーブルのデータをtest2ビューにリターンします。
上記内容をArticleControllerに変更を加えると以下の様になります。
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 |
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Article; use App\ArticleUser; class ArticleController extends Controller { // public function sayHello(){ return view('layout'); } public function test_hasMany_user2article(){ //ユーザ情報を取得 $users = ArticleUser::all(); return view('test.test1', ['users' => $users]); } public function test_belongsTo_article2user(){ //記事一覧を取得 $articles = Article::all(); return view('test.test2', ['articles' => $articles]); } } |
test1ビューファイルの新規作成
ビューは下記のディレクトリに格納します。
上記のディレクトリに新しくビューを作成します。このとき注意が必要なのはファイルの拡張子です。
ビューの拡張子は必ず.blade.phpにしてください。
[要件]
test1ビューファイルにはコントローラからArticleUsersテーブルのデータが送信されてきます。
hasManyを確認するため、ArticleUsersテーブル->articlesを使ってArticlesテーブルのデータを取得し表示させます。
画面に表示する内容として
・ユーザ名(ArticleUsersテーブル->user_name)
・記事ID(ArticleUsersテーブル->articles->Articlesテーブル->article_id)
上記内容を元にtest1ビューファイルを作成すると以下の様になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<!DOCTYPE HTML> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Test1</title> </head> <body> <h1>Hello World!</h1> @foreach($users as $user) <article> ============================<br> ユーザ名:{{$user->user_name}} <br> 記事ID: <br> @foreach($user->articles as $article) {{$article->article_id}} <br> @endforeach ============================<br> </article> @endforeach </body> </html> |
test2ビューファイルの新規作成
ビューは下記のディレクトリに格納します。
上記のディレクトリに新しくビューを作成します。このとき注意が必要なのはファイルの拡張子です。
ビューの拡張子は必ず.blade.phpにしてください。
[要件]
test2ビューファイルにはコントローラからArticlesテーブルのデータが送信されてきます。
belongsToを確認するため、Articlesテーブル->articleUserを使ってArticleUsersテーブルのデータなどを取得し表示させます。
画面に表示する内容として
・記事ID(Articlesテーブル->article_id)
・ユーザ名(記事投稿者)(Articlesテーブル->articleUser->ArticleUsersテーブル->user_name)
・カテゴリ名(Articlesテーブル->category->Categoriesテーブル->category_name)
・タグ名(Articlesテーブル->tag->Tagsテーブル->tag_name)
・タイトル(Articlesテーブル->detailedArticle->DetailedArticlesテーブル->title)
・投稿日(Articlesテーブル->detailedArticle->DetailedArticlesテーブル->published_date)
・内容(Articlesテーブル->detailedArticle->DetailedArticlesテーブル->body)
上記内容を元にtest2ビューファイルを作成すると以下の様になります。
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 |
<!DOCTYPE HTML> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Test2</title> </head> <body> <h1>Hello World!</h1> @foreach($articles as $article) <article> ============================<br> 記事ID::{{$article->article_id}} <br> 記事投稿者: {{$article->articleUser->user_name}} <br> カテゴリー: {{$article->category->category_name}} <br> タグ: {{$article->tag->tag_name}} <br> タイトル: {{$article->detailedArticle->title}} (投稿日:{{$article->detailedArticle->published_date}}) <br> 内容: {{$article->detailedArticle->body}} <br> ============================<br> </article> @endforeach </body> </html> |
ルーティングの変更
最後にコントローラとビューを紐づけるためにweb.phpに以下の変更をします。
1 2 |
Route::get('test1', 'ArticleController@test_hasMany_user2article'); Route::get('test2', 'ArticleController@test_belongsTo_article2user'); |
ブラウザで確認
test1の確認
test1ではhasManyを使って、ArticleUsersデータからArticlesデータを取得し表示できるかを確認します。
・ユーザ名(ArticleUsersテーブル->user_name)
・記事ID(ArticleUsersテーブル->articles->Articlesテーブル->article_id)
ブラウザ上で以下のURLにアクセスします。
以下の画像の様に表示されれば成功です。
ユーザ名はArticleUsersテーブルから入手しており、記事IDはhasManyを実装したarticlesメソッドでArticlesテーブルにアクセスして入手しています。
test2の確認
test2ではbelongsToを使って、Articlesデータからその他のデータベースからデータを取得し表示できるかを確認します。
・記事ID(Articlesテーブル->article_id)
・ユーザ名(記事投稿者)(Articlesテーブル->articleUser->ArticleUsersテーブル->user_name)
・カテゴリ名(Articlesテーブル->category->Categoriesテーブル->category_name)
・タグ名(Articlesテーブル->tag->Tagsテーブル->tag_name)
・タイトル(Articlesテーブル->detailedArticle->DetailedArticlesテーブル->title)
・投稿日(Articlesテーブル->detailedArticle->DetailedArticlesテーブル->published_date)
・内容(Articlesテーブル->detailedArticle->DetailedArticlesテーブル->body)
ブラウザ上で以下のURLにアクセスします。
以下の画像の様に表示されれば成功です。
ArticlesテーブルからbelongsToを実装した各データベースごとのメソッドでデータを入手して表示できています。
まとめ
今回はリレーションを定義して、データベース間でデータ取得できるようにしました。
そしてそのデータをビューで表示する方法もまとめました。
次はデータの表示画面に対して、Bootstrapを導入したいと思います。
次回記事
次回はBootstrapの導入方法についてまとめたいと思います。
前回記事
まとめページ
以上!