【Laravel入門】モデルの作成とシーディング


# モデルとは

超簡単に説明する。

MVCモデルのM。クライアントの要求がデータベース上のデータを必要とする場合に活躍する。

モデルはコントローラとデータベースの仲介を行い、必要なデータをコントローラに渡す。コントローラはそれを元にビューを作成する。そしてクライアントは、ブラウザ上でそのデータを見ることができる。

## Eloquentとは

Laravelのモデルは``Eloquent``のクラスに該当する。読み方は``「エロクアント」``だ。

このEloquentは``ORM（Object-Relational Mapping）``と呼ばれるもので、簡単に説明すると``データベースのテーブルやレコードをオブジェクトのように扱えるようにしてくれる仕組み``だ。

PHP自体``オブジェクト指向言語``なのだが、オブジェクト指向についての自分の理解はまだ浅い。しかし、早く学習を進めたいので細かい部分は省略する。

オブジェクトの概要は下記サイトの解説がわかりやすかったので、参考に紹介する。

[オブジェクト (object)とは](http://wa3.i-3-i.info/word1119.html)
[オブジェクト指向言語の種類と10の特徴](https://furien.jp/columns/102/#1-1)

話をEloquentに戻そう。

公式ドキュメントより（一部抜粋）

>Eloquent ORMはLaravelに含まれている、美しくシンプルなアクティブレコードによるデーター操作の実装です。それぞれのデータベーステーブルは関連する「モデル」と結びついています。モデルによりテーブル中のデータをクエリできますし、さらに新しいレコードを追加することもできます。

``アクティブレコード``はRuby on Railsに使用されているORMだ。アクティブレコードの仕組みがEloquentにも適用されている。

つまり、Eloquentは以下の役割を果たしているようだ。

- モデルによってデータベースとの結びつきを作る。
- 得たデータをPHPのオブジェクトの様にクラスやインスタンスとして扱わせてくれる。

解説はこれくらいにして、作業に進もう。

# モデルの作成

前回usersテーブルを作成したので、それを扱えるように``Userモデル``を作成する。モデルのファイルは``appディレクトリ``に作られる。

```
$ php artisan make:model User
```

さらに、後述する``getData()メソッド``も記述しておく。

```User.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    public function getData()
    {
        return '名前：'.$this -> name.'---メール：'.$this -> email;
    }
}
```

ここで気になったのがテーブルとの紐付けだ。（上記解説の「データベースとの結びつき」の部分だ。）どこにもusersテーブルを利用するという記述がない。しかし、そこは心配無用。

公式ドキュメントより（一部抜粋）

>モデルにどのテーブルを使用するか、Eloquentに指定していない点に注目してください。他の名前を明示的に指定しない限り、クラス名を複数形の「スネークケース」にしたものが、テーブル名として使用されます。

便利だなあ。ちなみに``スネークケース``はuser_idやarticle_titleのように``単語間をアンダーバーでつなぐ書き方``のことを言う。ちなみにuserIdやarticleTitleのように``単語間が大文字になる書き方``は、``キャメルケース``と言う。「ラクダのこぶ」を意味する名前だ。

## getDataメソッドの解説

ここでクラスやインスタンスが登場するが、このようなイメージで説明していく。

- クラスは設計図。
- インスタンスはクラスを元に作った実体。
- プロパティは属性。（「何」なのか）
- メソッドは操作。（「何をする」のか）
- インスタンスはプロパティやメソッドを持つことができる。

では、メソッドの内容を説明する。

- ``Userクラス``内で``getDataメソッド``を定義する。
- データベースから取り出されたレコードは``インスタンス``として扱われる。つまり、後述するコントローラの``$items = User::all();``で取り出されたデータは、全てインスタンスである。
- ``$this``はUserクラスを指す。
- Userクラスで得られたインスタンス（レコード）の``プロパティ``（nameカラムとemailカラム）をreturnで返している。

``$this``は``擬似変数``と呼ばれるもので、現在のクラスを表す変数だ。もちろん、今回はUserクラスを指している。

# コントローラの作成

次はUserコントローラを作成しよう。

```
$ php artisan make:controller UserController
```

早速編集する。Userモデルと紐づけるために``use App\User;``を忘れずに記載しよう。

```Usercontroller.php
<?php

namespace App\Http\Controllers;

use App\User;

use Illuminate\Http\Request;

class Usercontroller extends Controller
{
    public function index (Request $request)
    {
        $items = User::all();
        return view ('user.index', ['items' => $items]);
    }
}
```

## indexアクションの解説

- 引数である``Requestクラス``は、クライアントからのリクエスト情報を受け取り``$request``で扱う。（今回は具体的に使用されていないが・・・）
- ``User::all();``はusersテーブルの全レコードを取得するメソッドである。
- ``User::all();``で得たデータを配列``$items``に代入している。
- ``return文``により、``user.index``の中で``$items``を使用したビューが作成される。

ちなみに、return以下の部分は``compactメソッド``を使用した記述も可能だ。

```
return view ('user.index', compact('items'));
```

## allメソッドとは

公式ドキュメントより（一部抜粋）

>Eloquentのallメソッドはモデルテーブルの全レコードを結果として返します。Eloquentモデルはクエリビルダとしても動作しますのでクエリに制約を付け加えることもでき、結果を取得するにはgetメソッドを使用します。

先程の``allメソッド``は、``クエリビルダ``により``クエリ（データベースへの命令文）``として扱われて実行されていたのだ。クエリビルダについては公式ドキュメントに詳しく紹介されている。これは便利そうだ。

[Laravel 5.5 データベース：クエリビルダ](https://readouble.com/laravel/5.5/ja/queries.html)


# ルーティングの設定

Userコントローラのindexアクションが実行できるように、ルーティングを設定する。

```web.php
Route::get('/user/index', 'UserController@index');
```

# ビューの編集

２つの表示方法、つまりモデルのgetDataメソッドを使用する場合・しない場合を試してみる。まず共通の部分はこちら。

```views/user/index.blade.php
@extends('...common.layout')

@section('user_index')
    // 表示方法を記載
@endsection
```

こちらも忘れずに記載する。

```views/common/layout.blade.php
@yield('user_index')
```

## モデルのメソッドを使用した場合

配列$itemsから取り出した各データ``$item``対して、``getDataメソッド``が実行されている。

```
@foreach ($items as $item)
    {{ $item -> getData() }}<br>
@endforeach
```

## モデルのメソッドを使用しない場合

配列$itemsから取り出した各データ``$item``に対して、``アロー演算子``で``各プロパティ（nameとemail）``を取り出している。最初は、連想配列$itemsの添字（nameとemail）を使用して各要素を呼び出しているのかと思ったが、違っていた。

```
@foreach ($items as $item)
    名前：{{ $item -> name }}---メール：{{ $item -> email }}<br>
@endforeach
```

# シーディング

色々と動作確認を行う過程で、テスト用のデータが欲しいなと思った。

公式ドキュメントより（一部抜粋）

>シーダ（初期値設定）クラスを使用し、テストデーターをデーターベースに設定するシンプルな方法もLaravelには備わっています。全シーダクラスはdatabase/seedsに保存します。シーダクラスには好きな名前を付けられます。しかしUsersTableSeederなどのような分かりやすい規則に従ったほうが良いでしょう。デフォルトとしてDatabaseSeederクラスが定義されています。このクラスからcallメソッドを使い他の初期値設定クラスを呼び出すことで、シーディングの順番をコントロールできます。

これを使おう。シーディング用のライブラリも使用してみたいが、それはまた今度。

## シーダーの作成

```
$ php artisan make:seeder UsersTableSeeder
Seeder created successfully.
```

必要なファイルは全て``database/seedsディレクトリ``に作られる。

早速編集する。（コメントは削除した。）このシーダーで作成されるデータは1件だけだ。

ちなみに、ここで使用されているメソッドは先程のallメソッドとは少し系統が違う。``DBファザード``と呼ばれる仕組みが提供している``tableメソッド``だ。

ファザードについてはこちら。（公式ドキュメント）

[Laravel 5.5 ファサード
](https://readouble.com/laravel/5.5/ja/facades.html)

```UsersTableSeeder.php
<?php

use Illuminate\Database\Seeder;

class UsersTableSeeder extends Seeder
{
    public function run()
    {
        DB::table('users')->insert([
            'email' => str_random(10).'@gmail.com',
            'password' => bcrypt('secret'),
            'name' => str_random(10),
            'created_at' => new DateTime(),
            'updated_at' => new DateTime(),
        ]);
    }
}
```

``DatabaseSeeder.php``も編集する。（コメントは削除した。）

```DatabaseSeeder.php
<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    public function run()
    {
        $this->call(UsersTableSeeder::class);
    }
}
```

## シーディングの実行

以下のコマンドを実行すると、``DatabaseSeederクラス``の``runメソッド``が実行され、テスト用データが生成される。

```
$ php artisan db:seed
Seeding: UsersTableSeeder
```

複数のシーダーがある場合、特定のシーダーのみ選択して実行することも可能だ。しかし、この場合``Seeding: UsersTableSeeder``の表示が出ないため、テーブルを実際に確認しないと動作結果がわからない。

```
$php artisan db:seed --class=UsersTableSeeder
```

## データベースを綺麗にする

シーディングで作成したデータも含めて全て削除し、データベースを空にする場合はこちら。

```
php artisan migrate:refresh
```

``seedオプション``を使えば、データベースをリフレッシュし、その後全データベースのシーダーを実行してくれる。

```
php artisan migrate:refresh --seed
```

今回はここまで。