LoginSignup
23
30

More than 5 years have passed since last update.

【Laravel入門】CRUD実装〜新規登録

Last updated at Posted at 2018-05-05

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
2018_05_03_141933_create_articles_table.php
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.

これを下記の内容に編集する。

ArticleController.php
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つの機能がaddcreateの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アクションは、下記のような書き方もできる。

ArticleController.php
$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メソッドの違いでアクションを振り分けている。

web.php
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保護

公式ドキュメントより(一部抜粋)

Laravelでは、クロス・サイト・リクエスト・フォージェリ(CSRF)からアプリケーションを簡単に守れます。クロス・サイト・リクエスト・フォージェリは悪意のあるエクスプロイトの一種であり、信頼できるユーザーになり代わり、認められていないコマンドを実行します。

Laravelは、アプリケーションにより管理されているアクティブなユーザーの各セッションごとに、CSRF「トークン」を自動的に生成しています。このトークンを認証済みのユーザーが、実装にアプリケーションに対してリクエストを送信しているのかを確認するために利用します。

アプリケーションでHTMLフォームを定義する場合はいつでも、隠しCSRFトークンフィールドをフォームに埋め込み、CSRF保護ミドルウェアがリクエストの有効性をチェックできるようにしなければなりません。トークン隠しフィールドを生成するには、csrf_fieldヘルパ関数を使ってください。

以下の記事もCSRFについてわかりやすく説明されている。しかも、例として挙げられているのはLaravelだ。

PHPでCSRF対策の話

先ほど作成された_tokenプロパティはこの「トークン」のことだったのだ。

{{ csrf_field() }}のおかげで作成された_tokenプロパティと、各フィールド(入力画面)に記述された内容がtitleプロパティcontentプロパティの内容になり、POSTされてcreateアクションで処理されるのだ。

resources/views/article/add.blade.php
@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

こちらの記述も忘れずに。

resources/views/layouts/layout.blade.php
@yield('article_add')

モデル作成

Articleモデルを作成する。

$ php artisan make:model Article
Model created successfully.

下記の内容に編集する。

Article.php
<?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の公式サイトで説明されている。

PHP:アクセス権

protected $fillable'user_id'は、Userと連携させた後は必要がなくなる。今は値を空にすることができないため、とりあえず入力必須と設定しておく。

今回はここまで。

23
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
30