LaravelにおけるModel(Eloquent ORM)とは、データベースからのデータの出し入れを便利に簡単にLaravel上で行うため機能です。
この機能全体をEloquent(エロクワント)と呼び、そのエロクワント機能を使うためにModelと呼ばれるファイルを使います。
LaravelのModelとは?図で分かりやすく解説
まず、Modelというのはこれの事です。
Laravelプロジェクト→appフォルダの中にある、User.phpのような最初が大文字のphpファイルがModelです。デフォルトだとまだ空っぽか、User.phpだけがあると思います。
そこが分かってないと、モデルの理解はできないんだ。
コントローラーとデータベースについて、まずはこれらの記事を読んでよく理解して。
まず、Laravelのシステムをおさらいすると、下図のように、ページにアクセスがあった場合、
コントローラーがそのページの表示に必要なデータ(記事やコメントなど)をデータベースから取り出します。
Post321ページなら、Post321ページ用の記事や記事タイトルをコントローラーがデータベースから出しますし、プロフィールページにアクセスがあれば、プロフィール文章をデーターベースから出すわけです。
この必要なデータは、どうやってデータベースから出すかっていうと、「クエリ」と呼ばれる検索文を使って出します。
仮に下のようなデーターベースがあるとして、
ページを表示する際、postsテーブルのid1の情報だけ必要だとします。
その場合は、コントローラーが
select * from posts where id =1
(postsの中からidが1と合致する欄を全部ください!)
のようなクエリ(検索文)を出します。
で、こういう単純で短い検索ならモデルを無理に使う必要はないんです。モデルを使わなくても、Controllerに上のようなクエリ文を書く事で、普通にデータベースからデータを取り出せます。
ただ、これが複雑な検索文、「postsのID2-5の全部と、そのID2-5のポストを書いたユーザー名、及びユーザーがもらったいいね数をusersテーブルからもください。ただし、もしタイトル欄が空欄の場合は、よこさないでください」みたいな細かすぎて伝わらないだろ的な検索が必要な場合、
それを上のクエリ文で全部書こうとしたら、SQLに詳しい人じゃないとかなり難しく感じるはずです。(実際、こういう複雑な検索が口コミサイトなどを運営するなら頻繁に必要になります。)
そこで、そんな複雑検索も、もうちょっと簡単でPHP風なクエリ文で出せるようにと作られたのがEloquant(Model)なんです。
こんなふうに、モデルを介する事で、SQL文に詳しくない人でも複雑なクエリができるというわけなんです。
実際の例を出すと、例えば、知恵袋サイトでこういう投稿があったとします。
水色枠部分「投稿日、タイトル、本文、いいね数」はデータベースのpostsテーブルに入ってる情報です。
しかし、黄色枠部分、「投稿ユーザー名、ランク、使える言語、居住地」と言った部分は、usersテーブルに入ってます。
この場合、このpostを書いた人のuser情報のみをデータベースから取り出す必要があるため、モデルに付属しているRelation(リレーション)という機能を使わないと、データベースからうまく取り出せません。
こういった複雑な情報をより簡単に取り出すためにモデルを使うというわけです。
実際にLaravelのModelを作ってみよう。
では、実際にLaravelのModelを作ってみましょう。
コマンドプロンプト(ターミナル)を立ち上げて、
cd で Laravelプロジェクトフォルダまで移動したら、
php artisan make:model Postと入力、Enterします。
赤文字の部分がモデル名なんですが、
- 先頭を大文字
- モデル名はデータベースのテーブル名を単数形にした形
にする必要があります。
例えば、
posts テーブルなら、Post
users テーブルなら、User
people テーブルなら、Person
addresses テーブルなら、Address
のような具合です。
すると、appフォルダ内にモデルができます。
まだデータベースに元となるテーブルがないなら、同時に作る事もできるんだ。
例えば、
php artisan make:model Search -m
と入力すると、最後の-m がマイグレーションファイル作成の意味があるから、
自動的に、searches っていうファイルがdatabase\migrationsフォルダにできるよ。
そもそもマイグレーションが分かんない場合は↓
いや、実はローマ字やオリジナルな名称でも使える。
例えば、
php artisan make:model Kanji -m
とやった場合、
こんな具合に、Kanjiモデルとkanjisテーブルができる。
まぁ、バグ防止のために、やるならこの -m を使った同時作成コマンドで作るのがおすすめ。
モデル自体の解説はここまでで、
ここからは、モデルを使って実際にデータベースからデータを取り出すチュートリアルをやっていきます。
Laravelチュートリアル:Modelを使ったデータベースの呼び出し
では、実際にモデルを使って、
データベースから情報を引っ張り出す操作をやってみましょう。
*この記事ではLaravel6を使ってます。
フォームにユーザーID(数字)を入力すると、データベースから一致するユーザー名が呼び出されて、表示される仕組みを作ってみましょう。
まずは、Userモデルを作成(というか多分ある)
まず、appフォルダ内にUser.phpがあるか確認してください。
無い場合は、前項の方法で、Userモデルを作ってください。
中身はイジらなくていいです。
usersテーブルはあなたのデータベースにもすでにあるはずです。
phpMyAdminからチェックしてみてください。
(usersテーブルのマイグレーションファイルはLaravelインストール時に自動的に作成されているので、ただphp artisan migrateするだけで作成されます。)
→LaravelのMigrationとは?初心者でも図解で面白いほどよく分かる!
データベースにシーダーで仮のデーターを入れる
次にまだusersテーブルにデータがないと思いますので、シーダーという機能を使って、仮のユーザーを入れてみましょう。
ターミナルを開き、cd でLaravelプロジェクトフォルダに移動した後に、
php artisan make:seeder UsersTableSeeder
と入力しEnterしてください。(Usersのsを入れてください。)
database\seeds フォルダ内にUsersTableSeeder.phpが出来てるので、開いてください。
下の画像のように追記します。
まず、useの所に以下を追記します。
コピーしました
コピー
use App\User;
public function runの{ }の中に以下を追記します。
コピーしました
コピー
$data = [
'name' => 'kerotan',
'email' => 'kero@abc.com',
'password' => '12345',
];
$user = new User;
$user->fill($data)->save();
$data = [
'name' => '五右衛門',
'email' => 'goemon@goe.com',
'password' => '12345',
];
$user = new User;
$user->fill($data)->save();
$data = [
'name' => 'モンキー',
'email' => 'monk@saru.com',
'password' => '12345',
];
$user = new User;
$user->fill($data)->save();
あとは、上書き保存してください。
引き続き、同じseederフォルダ内にある DatabaseSeeder.phpを開きます。
自動的に、$this->call(UsersTableSeeder::class); という一文があると思うので、そのコメントアウト//だけ削除して上書き保存してください。
そしたら、コマンドプロンプト(ターミナル)に
php artisan db:seed と入力、Enterします。
このように出れば成功です。
もし、
のように出た場合は、どっかが抜けてたり間違ってるというエラーです。
エラーを探して修正し、もう一度php artisan db:seedします。
phpMyAdminで確認すると、無事名前とメールアドレスが入ってます。
コントローラーでモデルを使って、データを取り出す
では、実際に今作ったデータをModelを使って取り出してみましょう。
php artisan make:controller UserController
と入力、Enterして、UserControllerを作ります。
app\Http\Controllersフォルダ内に出来てるはずです。
ファイルを開いてください。
赤線、赤枠の部分を以下のように追記します。
コピーしました
コピー
use App\User;
→Laravelのuseとは?超初心者向けにシンプルに分かりやすく解説
コピーしました
コピー
public function test(Request $request)
{
$data = User::where('id', $request->id)->first();
return view('welcome')->with(['data' => $data]);
}
ちょっと説明しますね。
まず、public function test部分で、testファンクション(仕掛け)を作ってます。
Requestはフォームに入力された値(入力された文字や数字)を呼び出してます。
(LaravelのControllerのRequestとは?初心者でも図解と例でバッチリ分かる!)
次に、User::とモデルを呼び出します。User::と書く事で、すなわちusersテーブルからデータを検索するという意味になるんです。
そして、ここからはクエリ。User::where('id', $request->id)
で、usersテーブルのidカラム内を検索して、$request->id(フォームに入力された数字)と同じものがあれば、出してくれという意味です。
最後の->first();
は1つだけの値を取り出すという意味で、今回の場合、idは全部違う(同じIDは1つしかない)ので、firstを使ってます。例えば重複するIDがあって、両方とも取り出したい場合は、get()を使います。そしてそれを$data に代入してます(つまり$dataに今の検索結果が入る)。
return view('welcome')
の部分で、welcome.blade.phpを呼び出し、->with(['data' => $data]);
で、bladeに一緒に検索データを渡してます。
という流れです。
blade.phpの設定
後は、ブラウザに表示する部分であるblade.phpにフォームを設置します。
resources\viewsフォルダ内にあるwelcome.blade.phpを開いてください。(元からあるはずですが、なければ、テキストエディタで空のファイルに同名の名前を付ければOKです。)
このファイルを開くと、いろいろ書いてあると思うんですが、<div class="content">というタグを検索して、そのタグ間に以下のように追記して保存してください。(空のファイルでもこの赤枠部分だけ書けば動きます。)
コピーしました
コピー
<form method="post">
@csrf
<input type="text" name="id">
<input type="submit">
</form>
<p>{{$data->name ?? ''}}</p>
Laravelでは@csrfとフォームに入れないと、419 Page expiredというエラーが出ます。これはハッキング対策のタグなので必ず入れてください。
先程コントローラーで最後に->with(['data' => $data]);というタグを入れましたよね。その$dataが最後の{{$data->name ?? ''}}
に渡されて表示されます。じゃあ、->nameはなんなのかというと、データベースからは、一致するID丸ごと1行を受け取ってます。
この図で言えば、もしid2を呼び出したなら、name, password, email全部を呼び出してますから、
その中のnameだけ表示したいので、$data->name
って入力してるんです。
あと、最後の?? ''
は、もし$dataの中身が空っぽ、つまり検索結果がなしの時は、無視してくれという意味があります。そもそもフォームに何も入力しない場合は、$dataの中身がない状態で、welcome.blade.phpは呼び出されてしまいます。その時にエラーが出ないように付けるタグです。
ルーティングする
これで最後です。
routes\web.phpを開いてください。
まず、最初から書いてあるreturn view ('welcome')の奴を3行とも//を入れてコメントアウトします。ちなみに選択して、Ctrl+/ で高性能なエディタだと一発でコメントアウトできます。
そして、以下の二行を追記して保存してください。
コピーしました
コピー
Route::get('/', 'UserController@test');
Route::post('/', 'UserController@test');
getというのは、普通にブラウザからアクセスする事を意味し、postというのは、フォームを送信する事を意味します。今回は、TOPページに来たら、UserControllerのtestファンクションを呼び出し、フォームを送信した時も同じファンクションを呼び出すという設定になってます。
これで php artisan serve とコマンドプロンプト(ターミナル)に打ち込んでEnterし、http://localhost:8000/にアクセスすれば表示されるはずです。
フォームに1か2か3を入力し、送信してみてください。
このIDの列の名前が表示されるはずです。
さて、このように、Userモデルを作成して、User::where~のようなクエリを打ち、usersテーブルから値(データ)を引っ張り出してくるという流れが分かったでしょうか。
また最初に話したような複数テーブルからの取り出しも
それぞれのモデルにリレーションというコードを書く事で、可能になります。
これに関してはまた別の記事で解説+チュートリアルを作ります。