モデルとは
超簡単に説明する。
MVCモデルのM。クライアントの要求がデータベース上のデータを必要とする場合に活躍する。
モデルはコントローラとデータベースの仲介を行い、必要なデータをコントローラに渡す。コントローラはそれを元にビューを作成する。そしてクライアントは、ブラウザ上でそのデータを見ることができる。
Eloquentとは
LaravelのモデルはEloquentのクラスに該当する。読み方は「エロクアント」だ。
このEloquentはORM(Object-Relational Mapping)と呼ばれるもので、簡単に説明するとデータベースのテーブルやレコードをオブジェクトのように扱えるようにしてくれる仕組みだ。
PHP自体オブジェクト指向言語なのだが、オブジェクト指向についての自分の理解はまだ浅い。しかし、早く学習を進めたいので細かい部分は省略する。
オブジェクトの概要は下記サイトの解説がわかりやすかったので、参考に紹介する。
オブジェクト (object)とは
オブジェクト指向言語の種類と10の特徴
話をEloquentに戻そう。
公式ドキュメントより(一部抜粋)
Eloquent ORMはLaravelに含まれている、美しくシンプルなアクティブレコードによるデーター操作の実装です。それぞれのデータベーステーブルは関連する「モデル」と結びついています。モデルによりテーブル中のデータをクエリできますし、さらに新しいレコードを追加することもできます。
アクティブレコードはRuby on Railsに使用されているORMだ。アクティブレコードの仕組みがEloquentにも適用されている。
つまり、Eloquentは以下の役割を果たしているようだ。
- モデルによってデータベースとの結びつきを作る。
- 得たデータをPHPのオブジェクトの様にクラスやインスタンスとして扱わせてくれる。
解説はこれくらいにして、作業に進もう。
モデルの作成
前回usersテーブルを作成したので、それを扱えるようにUserモデルを作成する。モデルのファイルはappディレクトリに作られる。
$ php artisan make:model User
さらに、後述するgetData()メソッドも記述しておく。
<?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;を忘れずに記載しよう。
<?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メソッドは、クエリビルダによりクエリ(データベースへの命令文)として扱われて実行されていたのだ。クエリビルダについては公式ドキュメントに詳しく紹介されている。これは便利そうだ。
ルーティングの設定
Userコントローラのindexアクションが実行できるように、ルーティングを設定する。
Route::get('/user/index', 'UserController@index');
ビューの編集
2つの表示方法、つまりモデルのgetDataメソッドを使用する場合・しない場合を試してみる。まず共通の部分はこちら。
@extends('...common.layout')
@section('user_index')
// 表示方法を記載
@endsection
こちらも忘れずに記載する。
@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メソッドだ。
ファザードについてはこちら。(公式ドキュメント)
<?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も編集する。(コメントは削除した。)
<?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
今回はここまで。