Laravel - 11. モデル
マイグレーション、シーディングと見てきたので次はモデルについて取り上げます。MVCモデルおけるモデルとはビジネスロジックやデータを扱うものです。
一般的にLaravelのモデルはActive Recordパターンという考え方に沿っており、データベース上の1つのテーブルと対になるようにクラスを作成していきます。具体的には messages
テーブルに対応する Message
クラスを用意するという具合です。またモデルクラスの名前は名詞の単数形、テーブル名は複数形にしておくことが推奨されています。この規約を満たしている場合はモデルクラスを通じて、簡単にデータベース上のテーブルにアクセスできます。
このようなLaravelのデータベースとモデルを関連付ける仕組みは
Eloquent
と呼ばれるライブラリで定義されています。
それではモデルを作成してみましょう。モデルを作成するには php artisan make:model
コマンドを使います。
$ php artisan make:model モデルクラス名
ここでは messages
テーブルを操作する Message
モデルを作るので次のようにコマンドを入力します。
$ php artisan make:model Message
Model created successfully.
コマンドが成功すると app/Message.php
ファイルが生成されます。テキストエディタから app/Message.php
ファイルを開いてみましょう。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Message extends Model
{
//
}
生成された Message
クラスは Model
クラスを継承しています。現時点ではプロパティやメソッドの定義はありませんが、スーパークラスの Model
クラスのメソッドを通じて操作できるようになっています。また必要に応じてプロパティやメソッドを追加することも可能です。
モデルを操作する主要なメソッド
それではモデルに対して呼び出し可能なメソッドを確認しておきましょう。ここでは以下に示す主要なメソッドの呼び出しを試してみることにします。
操作 | モデルのメソッド呼び出し |
---|---|
レコードの全件取得 | $messages = Message::all(); |
IDによるレコードの取得 | $message = Message::find(1); |
1件目のレコードの取得 | $messages = Message::first(); |
レコードの条件指定 | $messages = Message::where("text", "Hello")->get(); |
レコードのソート指定 | $messages = Message::orderBy("text", "desc")->get(); |
レコードの作成 | $message = new Message(); $message->text = "Hola"; $message->save(); |
レコードの更新 | $message = Message::find(4); $message->text = "Adios"; $message->save(); |
レコードの削除 | $message = Message::find(4); $message->delete(); |
任意のselect文の実行 | DB::select("select * from messages"); |
コマンドラインでのモデルの操作
Laravelはコマンドラインでプログラムを評価する仕組みをサポートしています。コマンドラインでREPL環境としてのLaravelを起動するには php artisan tinker
コマンドを使います。
$ php artisan tinker
Psy Shell v0.10.4 (PHP 7.3.21 — cli) by Justin Hileman
>>>
php artisan tinker
コマンドを入力すると、コマンドラインからプログラムを入力できるようになります。
>>> 1 + 1
=> 2
>>> mb_strlen("Hello")
=> 5
>>>
上記のように演算や関数の呼び出しなどPHPのプログラムを記述してその場で実行・評価できます。
続いて作成した Message
クラスを使ってみましょう。まずは use App\Message
と入力して Message
クラスをインポートします。
>>> use App\Message
>>>
Message
モデルを参照できるようになったので、いくつかのメソッド呼び出しを試してみましょう。
まずはレコードの全件取得です。
>>> $messages = Message::all();
=> Illuminate\Database\Eloquent\Collection {#3864
all: [
App\Message {#3863
id: 1,
text: "Hello",
created_at: "2020-09-01 12:34:56",
updated_at: "2020-09-01 12:34:56",
},
App\Message {#3457
id: 2,
text: "Bonjour",
created_at: "2020-09-01 12:34:56",
updated_at: "2020-09-01 12:34:56",
},
App\Message {#3825
id: 3,
text: "Ciao",
created_at: "2020-09-01 12:34:56",
updated_at: "2020-09-01 12:34:56",
},
],
}
Message::all();
とすることで messages
テーブルから3件のレコードを取得しているのがわかります。また Message::all();
メソッドの戻り値は配列とよく似た Eloquent
の Collection
オブジェクトです。
モデルのメソッドを呼び出すことで、Laravelは内部的にSQLを発行しています。
次にIDによるレコードの取得を試してみましょう。
>>> $message = Message::find(1);
=> App\Message {#3929
id: 1,
text: "Hello",
created_at: "2020-09-01 12:34:56",
updated_at: "2020-09-01 12:34:56",
}
Message::find(1);
のように find
メソッドの引数にidを指定することで主キー検索となります。また Message::find(1);
メソッドの戻り値は Message
オブジェクトです。
次は1件目のレコードの取得を取得する方法です。
>>> Message::first();
=> App\Message {#4018
id: 1,
text: "Hello",
created_at: "2020-09-01 12:34:56",
updated_at: "2020-09-01 12:34:56",
}
Message::first();
とすることで先頭のレコードを1件だけ取得できます。メソッドの戻り値は Message
オブジェクトです。
次はレコードの条件指定です。
>>> $messages = Message::where("text", "Hello")->get();
=> Illuminate\Database\Eloquent\Collection {#3863
all: [
App\Message {#3864
id: 1,
text: "Hello",
created_at: "2020-09-01 12:34:56",
updated_at: "2020-09-01 12:34:56",
},
],
}
Message::where("text", "Hello")->get();
と指定することで where
句を指定したSQLを実行できます。メソッドの戻り値は Collection
オブジェクトです。
次はレコードのソート指定です。
>>> $messages = Message::orderBy("text", "desc")->get();
=> Illuminate\Database\Eloquent\Collection {#4078
all: [
App\Message {#3825
id: 1,
text: "Hello",
created_at: "2020-09-01 12:34:56",
updated_at: "2020-09-01 12:34:56",
},
App\Message {#3930
id: 3,
text: "Ciao",
created_at: "2020-09-01 12:34:56",
updated_at: "2020-09-01 12:34:56",
},
App\Message {#3457
id: 2,
text: "Bonjour",
created_at: "2020-09-01 12:34:56",
updated_at: "2020-09-01 12:34:56",
},
],
}
Message::orderBy("text", "desc")->get();
と指定することで order by
句を指定したSQLを実行できます。
where
メソッドとorder by
メソッドの呼び出して連鎖することも可能です。
次はレコードの作成です。
>>> $message = new Message();
=> App\Message {#3863}
>>> $message->text = "Hola";
=> "Hola"
>>> $message->save();
=> true
messages
テーブルにレコードを作成するには、Message
インスタンスを生成後、プロパティを設定し save
メソッドを呼び出します。 save
メソッドの呼び出しによって insert
文が発行されます。実際にレコードが作成されたかどうか確認してみましょう。
>>> Message::all();
=> Illuminate\Database\Eloquent\Collection {#4080
all: [
App\Message {#4081
id: 1,
text: "Hello",
created_at: "2020-09-01 12:34:56",
updated_at: "2020-09-01 12:34:56",
},
App\Message {#4082
id: 2,
text: "Bonjour",
created_at: "2020-09-01 12:34:56",
updated_at: "2020-09-01 12:34:56",
},
App\Message {#4083
id: 3,
text: "Ciao",
created_at: "2020-09-01 12:34:56",
updated_at: "2020-09-01 12:34:56",
},
App\Message {#4084
id: 4,
text: "Hola",
created_at: "2020-09-01 18:31:54",
updated_at: "2020-09-01 18:31:54",
},
],
}
あらたに4件目のレコードが登録されているのがわかります。
次はレコードの更新です。
>>> $message = Message::find(4);
=> App\Message {#4072
id: 4,
text: "Hola",
created_at: "2020-09-01 18:31:54",
updated_at: "2020-09-01 18:31:54",
}
>>> $message->text = "Adios";
=> "Adios"
>>> $message->save();
=> true
messages
テーブルの既存レコードを更新するには、 find
メソッドなどで取得した Message
インスタンスのプロパティを更新し save
メソッドを呼び出します。 save
メソッドの呼び出しによって update
文が発行されます。実際にレコードが更新されたかどうか確認してみましょう。
>>> Message::all();
=> Illuminate\Database\Eloquent\Collection {#4089
all: [
App\Message {#4090
id: 1,
text: "Hello",
created_at: "2020-09-01 12:34:56",
updated_at: "2020-09-01 12:34:56",
},
App\Message {#4091
id: 2,
text: "Bonjour",
created_at: "2020-09-01 12:34:56",
updated_at: "2020-09-01 12:34:56",
},
App\Message {#4092
id: 3,
text: "Ciao",
created_at: "2020-09-01 12:34:56",
updated_at: "2020-09-01 12:34:56",
},
App\Message {#4093
id: 4,
text: "Adios",
created_at: "2020-09-01 18:31:54",
updated_at: "2020-09-01 18:32:41",
},
],
}
4件目のレコードの text
項目が更新されているのがわかります。
次はレコードの削除です。
>>> $message = Message::find(4);
=> App\Message {#3929
id: 4,
text: "Adios",
created_at: "2020-09-01 08:31:54",
updated_at: "2020-09-01 08:32:41",
}
>>> $message->delete();
=> true
messages
テーブルの既存レコードを削除するには、 find
メソッドなどで取得した Message
インスタンスに対して delete
メソッドを呼び出します。 delete
メソッドの呼び出しによって delete
文が発行されます。実際にレコードが削除されたかどうか確認してみましょう。
>>> Message::all();
=> Illuminate\Database\Eloquent\Collection {#3863
all: [
App\Message {#3143
id: 1,
text: "Hello",
created_at: "2020-09-01 12:34:56",
updated_at: "2020-09-01 12:34:56",
},
App\Message {#4088
id: 2,
text: "Bonjour",
created_at: "2020-09-01 12:34:56",
updated_at: "2020-09-01 12:34:56",
},
App\Message {#4083
id: 3,
text: "Ciao",
created_at: "2020-09-01 12:34:56",
updated_at: "2020-09-01 12:34:56",
},
],
}
最後に Message
モデルの話から少しそれますが DB
ファサードを使ったSQLの実行方法も見ておきましょう。
>>> DB::select("select * from messages");
=> [
{#3148
+"id": 1,
+"text": "Hello",
+"created_at": "2020-09-01 12:34:56",
+"updated_at": "2020-09-01 12:34:56",
},
{#4026
+"id": 2,
+"text": "Bonjour",
+"created_at": "2020-09-01 12:34:56",
+"updated_at": "2020-09-01 12:34:56",
},
{#4079
+"id": 3,
+"text": "Ciao",
+"created_at": "2020-09-01 12:34:56",
+"updated_at": "2020-09-01 12:34:56",
},
]
上記のように DB::select
メソッドを使うことで任意のSELECT文を実行できます。 DB
ファサードには他にも insert
メソッドや update
メソッド、 delete
メソッドなどが用意されています。
Laravelで効率よくWebアプリケーションを開発するには Message
クラスのようなモデルを上手く活用することが大切です。複雑なSQLを実行するような特殊な要件においてはDB
ファサードを使用することも検討すると良いでしょう。
まとめ
- LaravelのモデルはEloquent ORMと呼ばれ、データベースとのやりとりを抽象化する仕組み
- 一般的なモデルはテーブルと対になるクラス(ActiveRecordパターン)
php artisan:model
コマンドでモデルクラスを作成できる