はじめに

「Cloud9を使ってLaravel5.4で開発」第2回です。

第一回はこちら

Cloud9を使ってLaravel5.4で開発【第1回】

最終目標は掲示板を作ることなんですが、まずは ユーザー一覧 をCRUDモデルで作成していきます。

今回のゴールはユーザー情報のindexページを表示する!です。

2.ユーザー 一覧(CRUD)を作成

2-1.テーブルやデータの準備

テーブルの準備

まずはテーブルを作成していく。

ここでは初期状態で存在しているmigration *1 ファイルを使う。

*1 migrationとは?

通常、データベースのテーブルを新規に作成したり、カラムの追加をするとなると必要なSQL文を直接実行することになる。

それに対してマイグレーションを使う場合にはまず、マイグレーションファイル と呼ばれるスクリプトファイルを作成し、プロジェクト内に保存。

その後コマンドライン上で後述するArtisanコマンドを使って実行をする。

例えば大人数でのプロジェクトなどでデータベースへの変更などがあった場合、チームの人はローカルでそのクエリを実行しなければならない。

しかし、マイグレーションを活用すれば、変更はファイルに保存されるため、更新を共有することが簡単になる。

database/migrations の中にあるファイルが migrationファイル。
このファイル内に、「○○というテーブルに××というカラムを作って・・・」という内容が書いてある。
今回は、このmigrationファイルは特に編集せずにデフォルトのままテーブル作成をしていく。

ターミナルで以下のArtisan *2 コマンドを実行。

※ ~/workspace にいる状態で

$ php artisan migrate

↑で
- usersテーブル
- migrationsテーブル
- password_resetsテーブル

ができる。
今回使用するのはusersテーブルだけ。

*2 artisanとは?

Artisan(アルチザン)とはLaravel専用のコマンド。

Macならターミナル、Windowsならコマンドラインで操作する。

Laravelプロジェクト上で実行し、実行すると、コントローラーやモデルの作成。マイグレーションの実行などが行える。

データの準備

ひとまず適当なデータをデータベースへ保存していく。
一つ一つデータを挿入していくのは めんどくさい 時間がかかってしまうので、

ここでは、Seeder *3 機能・Faker *4 機能を利用する。

*3 Seederとは?

テストデータをデータベースへ保存するための機能。LaravelではSeederクラスというものが定義され、その中でプログラムした内容がテストデータとしてデータベースに流し込まれる。

一覧の表示などを確かめたいが、データベースに一つ一つデータを保存するのは手間がかかるのでこういった機能を使う。

*4 Fakerとは?

前述のテストデータを作りたい時に、ダミーデータを生成してくれる機能。

Seederの生成
$ php artisan make:seeder UserSeeder

database/seeds/UserSeeder.php が生成される。

Seederの編集

database/seeds/UserSeeder.php を下記のように編集。

<?php

use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Supprot\Facades\DB;

use Faker\Factory as Faker;
use App\User;

class UserSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        // Userテーブルを一旦削除 truncateはIDもリセットされる
        User::truncate();

        // Fakerを使う ダミーデータを作成してくれる
        $faker = Faker::create('ja_JP');

        // insert レコードを25個挿入
        for($i=0;$i<25;$i++)
        {
            User::create([
                'name' => $faker->userName(),
                'email' => $faker->unique()->email(),
                'password' => $faker->password()
            ]);

        }
    }
}
Seeder実行

Artisanコマンドで実行する。

$ php artisan db:seed --class=UserSeeder

確認する。

ここでターミナルでMySQLへ入って直接 SELECT * FROM users と打っても良いのだが、ここで tinker *5 という機能を使ってみる。

*5 tinkerとは?

tinkerとはArtisanにあるコマンドのひとつで、コマンドライン上でPHPの構文を使いながら対話的にデータの挿入や参照が行える。

$ php artisan tinker
>>> App\User::all();

こんな感じでデータが見られる。

=> Illuminate\Database\Eloquent\Collection {#736
     all: [
       App\User {#737
         id: 1,
         name: "naoko.hirokawa",
         email: "nagisa.momoko@example.com",
         created_at: "2017-06-21 12:45:11",
         updated_at: "2017-06-21 12:45:11",
       },
       App\User {#738
         id: 2,
         name: "naoko26",
         email: "ltanabe@example.com",
         created_at: "2017-06-21 12:45:11",
         updated_at: "2017-06-21 12:45:11",
       },

~~~~~~~~~~~ 中略 ~~~~~~~~~~~~

       App\User {#760
         id: 24,
         name: "ftanabe",
         email: "hirokawa.rika@example.com",
         created_at: "2017-06-21 12:45:11",
         updated_at: "2017-06-21 12:45:11",
       },
       App\User {#761
         id: 25,
         name: "suzuki.akira",
         email: "rika.yoshimoto@example.com",
         created_at: "2017-06-21 12:45:11",
         updated_at: "2017-06-21 12:45:11",
       },
     ],
   }
>>>

データが挿入されていることが分かった。

ctrl + c で終了。

2-2.一覧表示を作る

ルーティング

ルーティングとは「ページを見ている人が example.com/index という URL にアクセスをしたら HogehogeControllerhoge() というメソッドを通りますよ」というような設定をしてあげること。
フレームワークにおいて大事な要素となる。

Laravelにおけるルーティングは、route/web.phpにまとめて記述していく。

ここでのルーティングは、/users で一覧が表示されるよう設定したいので、
route/web.phpRoute::get('/','function()... の下へ以下を記述。

  Route::get('users','UsersController@index')->name('users.index');

「HTTPリクエストが GEThttp://example.com/users にアクセスされたら、UsersControllerindex() メソッドを通ってね。別名(View名)は users.index だよ。」と記述してある。

別名については設定しなくても問題ないが、あとあと記述が楽になるのでつけておいた方がよい。

コントローラー

まずはコントローラーを生成する。

以下のArtisanコマンドを打つ。

$ php artisan make:controller UsersController

これで app/Http/Controllers の中に UsersController.php が生成される。

そうしたら

$ php artisan route:list

でルーティングを確認。

hogehoge:~/workspace $ php artisan route:list
+--------+----------+----------+-------------+--------------------------------------------+--------------+
| Domain | Method   | URI      | Name        | Action                                     | Middleware   |
+--------+----------+----------+-------------+--------------------------------------------+--------------+
|        | GET|HEAD | /        |             | Closure                                    | web          |
|        | GET|HEAD | api/user |             | Closure                                    | api,auth:api |
|        | GET|HEAD | users    | users.index | App\Http\Controllers\UsersController@index | web          |
+--------+----------+----------+-------------+--------------------------------------------+--------------+

こうなっていればOK。

では UsersController.php を以下のように編集し、実際の処理を記述していく。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\User;

class UsersController extends Controller
{
    public function index()
    {
        $users = User::orderBy('id','desc')->paginate(10);

        // 結果をビューに送る
        return view('users.index')->with('users',$users);
    }
}

$user = User::orderBy('id,'desc')->paginate(10); の部分について

ここでは
- orderBy で最新登録が先頭に来るように
- paginate で10行ごとにページング処理

とそれぞれ設定したかったので、上記のような記述となっている。

特にそのような設定がなければ、 $user = User::all(); とすれば users テーブルの全データが取得できる。

取得したデータは with() を利用し、ビューへ送る。

  view('view名')->with('viewでの変数名','実データ');

 という形になる。

ビュー

共通テンプレートを作る

Laravelではビュー用のファイルを .blade.php という形式で作成する。

まず共通のテンプレートファイルを resources/views/layouts/default.blade.php として新規作成。

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
</head>
<body>

    <div class="container">
        @yield('content')
    </div>

<!-- js -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script>
    @yield('script')
</script>
</body>
</html>

CSSはとりあえず bootstrap を利用。
この外枠に対して

@yield('content')

の中へ埋め込む各ページをこれから作っていく。

@yield('script')
の部分は、削除機能のところでJavaScriptを少し使うのでそのとき用。

一覧用の画面を作る

resources/views/ 以下に users フォルダを作成し、その中に index.blade.php を作成。

@extends('layouts.default')

@section('content')

    <h1>一覧表示</h1>

    <table class="table table-striped">
        @forelse($users as $user)
            <tr>
                <td>{{$user->id}}</td>
                <td>{{$user->name}}</td>
                <td>{{$user->email}}</td>
            </tr>
        @empty
          <p>ユーザーが存在しません</p>
        @endforelse
    </table>

    <!-- page control -->
    {!! $users->render() !!}

@endsection

@extends('layouts.default') で先ほど作成した共通レイアウトを読み込み、@section('content') ... @endsectionで content を定義している。

ここで一度画面を見てみる。

大きく Laravel の文字が出ていたページの URL に /users を足すとindexページが見られる。

74f4c3d5 f91e 439f b138 16b647e5ee1c

@forelseについて

foreach で配列を回すときに、「中身がなかったら別の処理をしたい」という場合、

今回であれば下の画像のように

A578a222 afd3 49c5 a6b0 c4f0e17ad3d4

こうしたい。

そのときに便利なのが forelse
本来であれば、

@if($users->count() > 0)
    @foreach($users as $user)
        // 処理
    @endforeach
@else
    <p>ユーザーが存在しません</p>
@endif

こう書く。

それが

@forelse($users as $user)
    // 処理
@empty
    <p>ユーザーが存在しません</p>
@endforelse

こう書ける。便利。

 

新規登録・詳細・編集・削除ボタンをつける

この後必要になる新規登録・詳細・編集・削除ボタンを用意する。
index.blade.php をさらに編集。

@extends('layouts.default')

@section('content')

    <h1>一覧表示</h1>

    <!-- 新規登録ボタン -->
    <div class="row">
        <div class="col-sm-12">
            <a href="/users/create" class="btn btn-primary" style="margin:20px;">新規登録</a>
        </div>
    </div>

    <!-- table -->
    <table class="table table-striped">

        <!-- loop -->
        @forelse($users as $user)
            <tr>
                <td>{{ $user->id }}</td>
                <td>{{ $user->name }}</td>
                <td>{{ $user->email }}</td>
                <td><a href="/users/{{ $user->id }}" class="btn btn-primary btn-sm">詳細</a></td>
                <td><a href="/users/{{ $user->id }}/edit" class="btn btn-primary btn-sm">編集</a></td>
                <td>
                    <form method="post" action="/users/{{ $user->id }}">
                        {{ csrf_field() }}
                        {{ method_field('DELETE') }}
                        <input type="submit" value="削除" class="btn btn-danger btn-sm btn-destroy">
                    </form>
                </td>
            </tr>
        @empty
            <p>ユーザーが存在しません</p>
        @endforelse
    </table>

    <!-- page control -->
    {!! $users->render() !!}

@endsection

こんな感じ。

B7ce776b 2ae7 4571 8eec 9cfe658b7df4

ここで出てきた csrf_field() について。

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

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

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

トークンとは本人であることを認証するために発行される、一度だけ有効なパスワードみたいなもの。

Laravelではセキュリティの面から、フォームを使うときにこのトークンが必須。

HTMLで実装すると、

<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">

こうなるのだけど、それを簡単に

{{ csrf_field() }}

こう書けますよという話。

今回はここまでです!
次回をお楽しみに!

Shere
  • はてなブログ
  • Twitter
  • Facebook
Cloud9を使ってLaravel5.4で開発【第2回】

Writer

  • Name

  • Position

    自然を愛する現代っ子

  • Profile

    文章を書くのは苦手です。小学校の読書感想文は毎年「五体不満足」でした。毎年同じのを出してました。そのくらい苦手です。でもブログ書きます。読んで下さい。