Webアプリを自作するためにPHPのフレームワークのLaravelを導入することに決めました。
PHP初心者かつLaravel初心者ですが、自分なりにスキルを得るためにLaravelを用いた記事投稿アプリを自作しました。その過程を備忘録としてまとめます。
最終的にはブラウザを利用して記事投稿画面の表示、ユーザごとの記事投稿数のグラフ化を目指したいと思います。
本記事は連載【投稿アプリ自作】の第九回目で、記事投稿の画面を作成する方法をまとめます。
※:Laravelは5.3からファイル構成が大幅に変わりました。本記事ではLaravel5.3以降を使って説明したいと思います。
※2:データベースはXAMPPに入っていたMySQLを使うことにします。事前にデータベースアカウントを登録しておいてください。
目次
目次
- 1 目次
- 2 ゴール
- 3 必要なもの
- 4 事前準備
- 5 Laravelソースファイルの変更
- 5.1 変更や新規作成するLaravelファイル一覧
- 5.2 laravelcollective/htmlパッケージをインストール方法
- 5.3 記事投稿画面用Viewファイルの新規作成
- 5.4 test2.blade.phpに記事新規作成ボタンを追加
- 5.5 ArticleControllerの変更
- 5.6 Articlesテーブルのモデルファイルの変更
- 5.7 ArticleUsersテーブルのモデルファイルの変更
- 5.8 Categoriesテーブルのモデルファイルの変更
- 5.9 DetailedArticlesテーブルのモデルファイルの変更
- 5.10 Tagsテーブルのモデルファイルの変更
- 5.11 ルーティングの変更
- 6 ブラウザで確認
- 7 まとめ
ゴール
本記事では、以下の2つについてまとめます。
・LaravelのViewでFormを記述するヘルパー関数が入っているlaravelcollective/html パッケージのインストール
・記事投稿画面の作成
以下の画像はlaravelcollective/htmlパッケージ内のヘルパー関数を使って作成した記事投稿画面になります。
本記事では、このような記事投稿画面を作成する方法についてまとめます。
必要なもの
必要なもの | 価格(円) | ||
---|---|---|---|
1 | PC | ピンキリ | |
備考 | インターネット接続可能なこと | ||
2 | XAMPP | 無料 | |
備考 | 持っていない場合は、こちらを参照→XAMPPのインストール方法 | ||
3 | Laravelフレームワーク | 無料 | |
備考 | インストールしていない場合は、こちらを参照→Laravelのインストール方法 | ||
4 | MySQLのデータベースアカウント | 無料 | |
備考 | 持っていない場合は、こちらを参照→phpMyAdminでデータベースとユーザを新規登録する | ||
5 | 投稿アプリ向けのテーブル | 無料 | |
備考 | 【投稿アプリ自作】の第四回目で作成した投稿アプリ向けのテーブルです。持っていない場合は、こちらを参照→【投稿アプリ自作(4)】テーブル設計とマイグレーション実行(Laravel) | ||
6 | ダミーデータ | 無料 | |
備考 | 【投稿アプリ自作】の第六回目で作成した投稿アプリ向けのダミーデータです。持っていない場合は、こちらを参照→【投稿アプリ自作(6)】seederでダミーデータの作成(Laravel) | ||
7 | 投稿表示画面 | 無料 | |
備考 | 【投稿アプリ自作】の第七回目で作成した投稿アプリ向けのダミーデータを表示する画面(記事表示画面)です。持っていない場合は、こちらを参照→【投稿アプリ自作(7)】リレーショナルデータベースからデータを取得・表示する(Laravel) |
事前準備
テーブルの作成
事前に投稿アプリ向けのテーブルを用意する必要があります。
第四回目でテーブル設計と新規テーブルの作成方法をまとめていますので、まだ作成していない方は以下の記事を参考にして新規テーブルの作成をしてください。
テーブルの関連性
投稿アプリ向けのテーブルの関連性をER図にまとめると下の様になります。(IDEDF1X記法で記述)
※ネットで検索しながら見よう見まねで書いたので間違っているかもしれませんがご容赦ください。
ダミーデータの作成
本記事でアクセスするためのダミーデータが必要です。
前回の記事でダミーデータの作成方法をまとめていますので、ダミーデータがない場合は以下の記事を参考にダミーデータの作成をしてください。
ダミー記事表示画面の作成
本記事で作成した記事投稿画面の結果を確認するために記事表示画面が必要です。
前回の記事で記事表示画面の作成方法をまとめていますので、記事表示画面がない場合は以下の記事を参考に記事表示画面の作成をしてください。
Laravelソースファイルの変更
変更や新規作成するLaravelファイル一覧
Laravelのプロジェクトファイル配下にあるファイルで本記事の中で変更、新規作成するファイルについてまとめました。
ファイル名 | 対応 | 備考 | |
---|---|---|---|
1 | config/app.php | 変更 | |
2 | resources/views/test/create.blade.php | 新規追加 | |
3 | resources/views/test/test2.blade.php | 変更 | |
4 | app/Http/Contoroller/ArticleController.php | 変更 | |
5 | app/Article.php | 変更 | |
6 | app/ArticleUser.php | 変更 | |
7 | app/Category.php | 変更 | |
8 | app/DetailedArticle.php | 変更 | |
9 | app/Tag.php | 変更 | |
10 | routes/web.php | 変更 |
laravelcollective/htmlパッケージをインストール方法
Laravel のViewでFormを記述するには以下の2通りあります。
1.直接HTMLを記述する方法
2.ヘルパー関数を使う方法
本記事では2番の「ヘルパー関数を使う方法」を使って投稿画面のFormを作成します。
そのためにヘルパー関数が入っているlaravelcollective/htmlパッケージをインストールします。
laravelcollective/htmlパッケージをインストール
laravelcollective/htmlパッケージをインストールするには以下のコマンドをコマンドプロンプト上で実行します。
laravelcollective/htmlパッケージを組み込む
config/app.php にlaravelcollective/htmlのクラスを設定します。
※この辺の設定や仕組みは Laravel ではサービスプロバイダーとか、ファサードというみたいです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?php // config/app.php return [ // サービス・プロバイダーの登録 'providers' => [ // ... //laravelcollective/html パッケージ Collective\Html\HtmlServiceProvider::class, ], // ファサードの登録 'aliases' => [ // ... //laravelcollective/html パッケージ 'Form' => Collective\Html\FormFacade::class, 'Html' => Collective\Html\HtmlFacade::class, ], ]; |
laravelcollective/html パッケージの使用方法
上でインストールしたlaravelcollective/html パッケージを使用して記事投稿画面用のViewファイルを作成しますが、その前にlaravelcollective/html パッケージの使い方をまとめたいと思います。
laravelcollective/htmlパッケージを組み込むの章でファザードとして「‘Form’ => Collective\Html\FormFacade::class,」を追加しました。
これにより、Form::とコールすることでCollective\Html\FormBuilderクラスのインスタンスメソッドをコールする意味になります。
これがファザードという機能のようです。ファザードは奥が深そうで、私もあまり理解できたいません。。。
何はともあれ、Form::と記述すればlaravelcollective/html パッケージが使用できるようになります。
以下ではlaravelcollective/html パッケージのメソッドと機能を簡単にまとめました。
詳しくは下記のAPIリファレンスで確認してください。
laravelcollective/htmlのAPIリファレンス
メソッド | 概要 | 備考 | |
---|---|---|---|
1 | Form::open() | formの開始タグを生成 | |
2 | Form::close() | formの終了タグを生成 | |
3 | Form::token() | CSRFトークンを生成 | POST, PUT ,DELETEを使ったときにhidden要素に自動でCSRFトークンが追加される。 |
4 | Form::model() | モデルからFormの開始タグを生成 | Form::openの代わりに、Form::modelメソッドを使うと、Formの要素にモデルのプロパティ(テーブルのフィールド)を紐付けることが出来るようになる。※終了タグForm::close()を忘れないようにすること |
5 | Form::label() | labelタグを生成 | |
6 | Form::text() | input[type=text]タグを生成 | |
7 | Form::password() | input[type=password]タグを生成 | |
8 | Form::email() | input[type=email]タグを生成 | |
9 | Form::file() | input[type=file]タグを生成 | |
10 | Form::checkbox() | input[type=checkbox]タグを生成 | |
11 | Form::radio() | input[type=radio]タグを生成 | |
12 | Form::number() | input[type=number]タグを生成 | |
13 | Form::date() | input[type=date]タグを生成 | |
14 | Form::select() | selectタグを生成 | |
15 | Form::submit() | input[type=submit]タグを生成 | |
16 | Form::macro() | 独自のFormマクロを生成 | |
17 | link_to() | URLからHTMLリンクを生成 |
記事投稿画面用Viewファイルの新規作成
以下のViewファイルを新規作成します。
※本記事では「create.blade.php」というファイル名にしています。
Form::XXXXはlaravelcollective/html パッケージのファザードを使っています。
詳しくはlaravelcollective/html パッケージの使用方法の章を参照してください。
また、class=”xxxx”の指定は、Bootstrapを使用しています。
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 |
@extends('layout') @section('content') <h1>新規記事投稿ページ</h1> <hr/> {!! Form::open(['url' => 'articles']) !!} <B>Select UserName:</B></br> <select class="form-control" name="user_name"> <option value="" selected="selected">選択してください</option> @foreach($user_names as $user_name) <option value={{$user_name}}>{{$user_name}}</option> @endforeach </select> <div class="form-group"> {!! Form::label('title', 'Title:') !!} {!! Form::text('title', null, ['class' => 'form-control']) !!} </div> <div class="form-group"> {!! Form::label('body', 'Body:') !!} {!! Form::textarea('body', null, ['class' => 'form-control']) !!} </div> <B>Select Category:</B></br> <select class="form-control" name="category_name"> <option value="" selected="selected">選択してください</option> @foreach($category_names as $category_name) <option value={{$category_name}}>{{$category_name}}</option> @endforeach </select> <B>Select tag:</B></br> <select class="form-control" name="tag_name"> <option value="" selected="selected">選択してください</option> @foreach($tag_names as $tag_name) <option value={{$tag_name}}>{{$tag_name}}</option> @endforeach </select> <div class="form-group"> {!! Form::label('published_date', 'Publish On:') !!} {!! Form::input('date', 'published_date', date('Y-m-d'), ['class' => 'form-control']) !!} </div> <div class="form-group"> {!! Form::submit('Add Article', ['class' => 'btn btn-primary form-control']) !!} </div> {!! Form::close() !!} @endsection |
test2.blade.phpに記事新規作成ボタンを追加
link_to()を使って’articles/create’へのリンクタグを作成しています。
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 |
@extends('layout') @section('content') <h1>Test2</h1> {!! link_to('articles/create', '新規作成', ['class' => 'btn btn-primary']) !!} @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 @endsection |
ArticleControllerの変更
新規に3つのメソッドを追加しました。
・index()
->記事一覧を取得して表示するメソッド
・create()
->新規記事を作成するときに使用されるメソッド
・store()
->新規記事が登録されるときに使用されるメソッド
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 |
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Article; use App\DetailedArticle; use App\ArticleUser; use App\Category; use App\Tag; use DB; class ArticleController extends Controller { public function index() { //記事一覧を取得 $articles = Article::all(); return view('test.test2', ['articles' => $articles]); } public function create(){ $user_names = ArticleUser::pluck('user_name'); $category_names = Category::pluck('category_name'); $tag_names = Tag::pluck('tag_name'); return view('test.create', ['user_names' => $user_names,'category_names' =>$category_names,'tag_names' => $tag_names]); } public function store(Request $request) { $user_id = ArticleUser::ofUser_Name($request->user_name)->first()->user_id; $user_article_max_id = Article::ofUser_Id($user_id)->max('user_article_id'); $user_article_id = $user_article_max_id + 1; $category_id = Category::ofCategory_Name($request->category_name)->first()->category_id; $tag_id = Tag::ofTag_Name($request->tag_name)->first()->tag_id; $article = Article::create([ 'user_id' => $user_id, 'user_article_id' => $user_article_id, 'category_id' => $category_id, 'tag_id' => $tag_id ]); DetailedArticle::create([ 'article_id' => $article->article_id, 'title' => $request->title, 'body' => $request->body, 'published_date' => date($request->published_date) ]); //記事一覧へリダイレクト return redirect('articles'); } 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]); } } |
Articlesテーブルのモデルファイルの変更
変更点は以下
1.以下のカラムを編集可能に変更
・user_id
・user_article_id
・category_id
・tag_id
2.user_idから特定の行を取得できるクエリスコープscopeOfUser_Id()を作成
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 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Article extends Model { protected $table = 'articles'; protected $primaryKey = "article_id"; protected $fillable = ['user_id', 'user_article_id', 'category_id','tag_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'); } //クエリースコープ public function scopeOfUser_Id($query, $user_id){ return $query->where('user_id',$user_id); } } |
ArticleUsersテーブルのモデルファイルの変更
変更点は以下
1.以下のカラムを編集可能に変更
・user_name
・password
・gender
・mail_address
2.user_nameから特定の行を取得できるクエリスコープscopeOfUser_Name()を作成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class ArticleUser extends Model { protected $table = 'article_users'; protected $primaryKey = "user_id"; protected $fillable = ['user_name', 'password', 'gender','mail_address']; public function articles(){ return $this->hasMany('App\Article','user_id'); } //クエリースコープ public function scopeOfUser_Name($query, $user_name){ return $query->where('user_name',$user_name); } } |
Categoriesテーブルのモデルファイルの変更
変更点は以下
1.以下のカラムを編集可能に変更
・category_name
2.category_nameから特定の行を取得できるクエリスコープscopeOfCategory_Name()を作成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Category extends Model { protected $table = 'categories'; protected $primaryKey = "category_id"; protected $fillable = ['category_name']; public function articles(){ return $this->hasMany('App\Article','category_id'); } //クエリースコープ public function scopeOfCategory_Name($query, $category_name){ return $query->where('category_name',$category_name); } } |
DetailedArticlesテーブルのモデルファイルの変更
変更点は以下
1.以下のカラムを編集可能に変更
・article_id
・title
・body
・published_date
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class DetailedArticle extends Model { protected $table = 'detailed_articles'; protected $primaryKey = "article_id"; protected $fillable = ['article_id', 'title', 'body','published_date']; public function articles(){ return $this->hasOne('App\Article','article_id'); } } |
Tagsテーブルのモデルファイルの変更
変更点は以下
1.以下のカラムを編集可能に変更
・tag_name
2.tag_nameから特定の行を取得できるクエリスコープscopeOfTag_Name()を作成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Tag extends Model { protected $table = 'tags'; protected $primaryKey = "tag_id"; protected $fillable = ['tag_name']; public function articles(){ return $this->hasMany('App\Article','tag_id'); } //クエリースコープ public function scopeOfTag_Name($query, $tag_name){ return $query->where('tag_name',$tag_name); } } |
ルーティングの変更
最後に以下の3行をweb.phpに追加する。
1 2 3 |
Route::get('articles', 'ArticleController@index'); Route::get('articles/create', 'ArticleController@create'); Route::post('articles', 'ArticleController@store'); |
ブラウザで確認
記事一覧と新規作成ボタンの確認
ブラウザ上で以下のURLにアクセスします。
すると、下の画像の様に記事一覧と一番上に新規作成ボタンが出力されるはずです。
新規記事投稿画面の確認
記事一覧と新規作成ボタンの確認で確認したページの”新規作成”ボタンをクリックします。
すると、下の画像の様に新規記事投稿画面が表示されるはずです。
新規記事投稿できるかを確認
新規記事投稿画面で下の様にダミーデータを入力して”Add Article”ボタンをクリックしました。
すると、記事一覧画面に戻り、一番下に先ほどの記事が投稿できたことを確認できました。
まとめ
今回はlaravelcollective/htmlパッケージを使って、新規記事投稿画面の作成をしました。
これで表示、新規作成と基本的なところはできました。
もともとLaravelを使ってグラフ描画もやりたかったので、次回はグラフ描画ライブラリを導入してユーザごとの記事投稿数をグラフを作成したいと思います。
次回記事
これで新規記事作成画面ができました。
次回はグラフ描画ライブラリを導入してユーザごとの記事投稿数をグラフにする方法についてまとめたいと思います。
前回記事
まとめページ
以上!