CRUDとは
Wikipediaより(一部抜粋)
CRUD(クラッド)とは、ほとんど全てのコンピュータソフトウェアが持つ永続性[1]の4つの基本機能のイニシャルを並べた用語。その4つとは、Create(生成)、Read(読み取り)、Update(更新)、Delete(削除)である。ユーザインタフェースが備えるべき機能(情報の参照/検索/更新)を指す用語としても使われる。
どのようなアプリを作ろうとも必須になる機能だ。これから投稿機能を実装していくが、CRUDに沿って機能を追加していく。今回作成する機能はCreate(生成)
だ。
なお、Userとの連携(リレーション)については後で作業を行う。
テーブル作成
作成するアプリは掲示板形式にしたい。まず、投稿記事を格納するarticlesテーブル
を作成する。
まずはマイグレーションファイルを作成する。
$ php artisan make:migration create_articles_table
Created Migration: 2018_05_03_141933_create_articles_table
次にマイグレーションファイルを編集する。デフォルトで作成されるidカラムとtimestamps()はそのままにし、以下のカラムを追記する。
- user_id(後にUserとの連携で必要になる。)
- title
- content
public function up()
{
Schema::create('articles', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id');
$table->string('title');
$table->string('content');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('articles');
}
最後にマイグレーションを行う。これでarticlesテーブルが作成された。
$ php artisan migrate
Migrating: 2018_05_03_141933_create_articles_table
Migrated: 2018_05_03_141933_create_articles_table
#コントローラ作成
Articleコントローラ
を作成する。
$ php artisan make:controller ArticleController
Controller created successfully.
これを下記の内容に編集する。
public function add()
{
return view('article.add');
}
public function create(Request $request)
{
$article = new Article;
$article->user_id = $request->user_id;
$article->title = $request->title;
$article->content = $request->content;
$article->save();
return redirect('/');
}
今回実装する機能はCRUDのCreate(生成)
つまりarticleの新規登録機能
だ。しかし、1つの機能がadd
とcreate
の2つのアクションに別れている。これを説明していく。
addアクション
- addアクションは
articleの新規登録画面を表示
させる。そのためHTTPメソッド
はGET
となる。 -
GET
のため、アクション側で受け取る情報(ユーザーが作成した記事)、つまり$request
に代入すべき情報がない。そのため引数は必要ない。 - 入力画面
'article.add'ビュー
を表示する。
createアクション
- createアクションは
article作成に必要な項目を入力後、送信ボタンをクリックしその内容を送信した後
にarticlesテーブルにデータを格納する
ために行われる。そのためHTTPメソッド
はPOST
となる。 - 引数に
Request $request
を指定すると、Requestクラス
により作成されたHTTPリクエストインスタンス
が$request
に代入される。当然HTTPメソッド
もHTTPリクエストインスタンス
に含まれている。 - そのため、
$request
にはPOSTで受け取った情報(ユーザーが作成した記事)
が入っている。 -
new Article
でインスタンスを新規作成し、$article
へ代入する。 -
$request
から各プロパティ
を呼び出す。 - プロパティの呼び出しには
->(アロー演算子)
が使われている。 - 呼び出されたプロパティを
$articleの各プロパティとして代入
する。 - モデルの
saveメソッド
を実行し、内容をデータベースに書き込む。 - 上記の作業が終わったら、
'/(トップページ)'ビュー
へリダイレクトする。
createアクションは、下記のような書き方もできる。
$article = new Article;
$form = $request->all();
unset($form['_token']);
$article->fill($form)->save();
return redirect('/');
-
new Article
でインスタンスを生成し、$article
へ代入する。 - モデルの
allメソッド
で$request
から全てのプロパティを呼び出し、$form
に代入する。 - 全てのプロパティを取得すると必要のない
_tokenプロパティ
まで取得してしまうので、モデルのunsetメソッド
でこれを削除する。 -
_tokenプロパティ
はセキュリティ対策の一環として作成されてる。 - モデルの
fillメソッド
で$articleインスタンスのプロパティ
を$formの内容に指定する。 - モデルの
saveメソッド
を実行し、内容をデータベースに書き込む。 -
'/(トップページ)'ビュー
へリダイレクトする。
ちなみにfillメソッド
のプロパティ指定は、$article->fill(['title' => 'test']);
のように配列形式で行うことが可能だ。
ここでモデルのメソッドが頻繁に使用されているが、これは後に作成するモデルArticle.php
の中で、Articleクラス
がclass Article extends Model
の記述でModelクラス
を継承しているため、使用できるのだ。
ルーティング設定
下記の内容を追記する。
同じ'/article/add'
アドレスへアクセスしても、HTTPメソッドの違いでアクションを振り分けている。
Route::get('/article/add', 'ArticleController@add')->name('article_add');
Route::post('/article/add', 'ArticleController@create')->name('article_create');
ビュー作成
resources/viewsディレクトリ
にarticleディレクトリ
を作成し、必要なファイルを作成する。正直、レイアウトは最低限以下だ。これは動作確認だと言い訳をしつつ、先に進む。
一見通常の入力フォームに見えるが、見慣れない一文がある。{{ csrf_field() }}
とは何だろうか?詳細は公式ドキュメントで・・・
[Laravel 5.5 CSRF保護]
(https://readouble.com/laravel/5.5/ja/csrf.html)
公式ドキュメントより(一部抜粋)
Laravelでは、クロス・サイト・リクエスト・フォージェリ(CSRF)からアプリケーションを簡単に守れます。クロス・サイト・リクエスト・フォージェリは悪意のあるエクスプロイトの一種であり、信頼できるユーザーになり代わり、認められていないコマンドを実行します。
Laravelは、アプリケーションにより管理されているアクティブなユーザーの各セッションごとに、CSRF「トークン」を自動的に生成しています。このトークンを認証済みのユーザーが、実装にアプリケーションに対してリクエストを送信しているのかを確認するために利用します。
アプリケーションでHTMLフォームを定義する場合はいつでも、隠しCSRFトークンフィールドをフォームに埋め込み、CSRF保護ミドルウェアがリクエストの有効性をチェックできるようにしなければなりません。トークン隠しフィールドを生成するには、csrf_fieldヘルパ関数を使ってください。
以下の記事もCSRFについてわかりやすく説明されている。しかも、例として挙げられているのはLaravelだ。
先ほど作成された_tokenプロパティ
はこの「トークン」のことだったのだ。
{{ csrf_field() }}
のおかげで作成された_tokenプロパティ
と、各フィールド(入力画面)に記述された内容がtitleプロパティ
、contentプロパティ
の内容になり、POSTされてcreateアクションで処理されるのだ。
@extends('...layouts.layout')
@section('article_add')
投稿作成<br>
<form action='{{ route('article_create') }}' method='post'>
{{ csrf_field() }}
ユーザーID:<input type='text' name='user_id'><br>
タイトル:<input type='text' name='title'><br>
内容:<input type='text' name='content'><br>
<input type='submit' value='投稿'>
</form>
@endsection
こちらの記述も忘れずに。
@yield('article_add')
モデル作成
Articleモデル
を作成する。
$ php artisan make:model Article
Model created successfully.
下記の内容に編集する。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
protected $fillable = ['user_id', 'title', 'content'];
}
protected $fillable = ['user_id', 'title', 'content'];
を記述しなくてもアプリは動くのだが、セキュリティのために記述しなければならない。管理者側からすれば、ユーザーから編集されては困る項目(プロパティ)もある。それらの項目を、あらかじめホワイトリストやブラックリストとして指定する機能だ。
ホワイトリストによる指定
- 入力できる項目を限定する。
- モデルの
$fillableプロパティ
を使用する。 -
protected $fillable = ['user_id', 'title', 'content'];
と記述した場合、Articleモデル
のuser_id属性、title属性、content属性のみ入力可能
となる。
ブラックリストによる指定
- 入力できない項目を指定する。
- モデルの
$guardedプロパティ
を使用する。 -
protected $guarded = ['id'];
と記述した場合、Articleモデル
のid属性の入力が不可能
となる。
ちなみにprotected
はアクセス修飾子
と呼ばれるものだ。protected以下に記述したコードは、Articleクラスとサブクラスにのみ適用される。これはPHPの公式サイトで説明されている。
protected $fillable
の'user_id'
は、Userと連携させた後は必要がなくなる。今は値を空にすることができないため、とりあえず入力必須と設定しておく。
今回はここまで。