LaravelのModelの使い方について解説しています。
載せているコマンドやサンプルコードは、Laravelのバージョン9.0.2を使用して確認しています。
LaravelのModel(モデル)について
LaravelのModelは、データベースとデータをやりとりするために作成します。
モデルを使うことで、LaravelのORMであるEloquentの機能を使って、データの取得や追加・更新などを行うことができます。
基本的には、テーブルとモデルは1対1になります。
Laravelに接続設定しているデータベースのひとつのテーブルにつき、ひとつのモデルを用意します。
LaravelのModelを作成する
LaravelのModelもartisanコマンドを使用することで作成できます。
下記のようにコマンドを実行することで、モデルを作成できます。
$ php artisan make:model Fruit
コマンドを実行すると、下記のようにモデルが作成されたことが確認できます。
$ php artisan make:model Fruit
Model created successfully.
実際に作成されたモデルを確認すると、下記のようにModelが作成されています。
デフォルトでは、app/Models
配下にモデルが作成されるようになっています。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Fruit extends Model
{
use HasFactory;
}
モデルと一緒にマイグレーションを作成する
データベースに新しいテーブルを作成するマイグレーションをモデルと一緒に作成することが可能です。
その場合にはモデルを作成するコマンドに-m
オプションをつけて実行します。
$ php artisan make:model Fruit -m
実行すると、下記のようにモデルファイルと一緒にマイグレーションファイルも作成されます。
$ php artisan make:model Fruit -m
Model created successfully.
Created Migration: 2022_05_04_081825_create_fruits_table
※-m
は--migration
オプションの省略形です。--migration
を指定しても良いです。
LaravelのModelの命名規則
LaravelのModelの名前はテーブルに対して、単数形で書くように決まっています。
例えば、テーブル名がusersの場合はモデル名はUserになります。
先ほどのようにテーブル名がfruitsの場合はモデル名はFruitです。
複数の単語でテーブルを作成する場合は、アンダーバーで繋ぐスネークケースになります。
対応するモデルはキャメルケースで書きます。
例えば、テーブル名がuser_fruitsの場合はモデル名はUserFruitになります。
このように、テーブル名とモデル名を決められた規則で作成することで、Eloquentを使用して対象のテーブル操作が可能です。
先ほどのコマンドを使用して、モデルと一緒にマイグレーションファイルを作成するとテーブル名をつけてくれるので楽です。
モデルを別のテーブルに繋ぐには?
モデルを決められた名前のテーブル以外の別テーブルに繋ぎたい場合についてです。
その場合は、モデルクラスに下記のように$table
プロパティを作成することで、別テーブルに設定できます。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Test extends Model
{
use HasFactory;
protected $table = 'fruits';
}
上記はTestモデルなので、テーブルはtests
になります。
ですが、$table
を用意してfruits
を設定したので、fruits
テーブルに対して操作ができるようになります。
fillableとguardedについて
Laravelでデータを追加するためにcreateメソッドを使用しますが、使うためにはfillable
かguarded
の設定が必要です。
fillableにはデータ登録許可するカラムを指定します。
guardedにはデータ登録をさせないカラムを指定します。
fillableの設定
例えば、先ほど作成したFruitモデルにfillableを指定する場合は、下記のようにします。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Fruit extends Model
{
use HasFactory;
protected $fillable = ['name', 'color', 'price'];
}
登録可能なカラムを全て指定します。
指定されたカラム以外には登録できません。
guardedの設定
guardedに指定する場合は、下記のようにします。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Fruit extends Model
{
use HasFactory;
protected $guarded = ['created_at', 'updated_at'];
}
入力させないカラムを指定します。
指定したカラム以外にはデータ登録できます。
fillableとguardedのどちらを使うか
基本的には作成したカラムの全部に対してデータを入れるかと思います。
guardedを使って、Laravelが自動的に入れてくれるタイムスタンプ(created_at
・updated_at
)だけ指定する方が楽なのかと思います。
入力するカラムが少ない場合などにfillableを使うようにすると良いのではないでしょうか。
データを取得するときにカラムを隠す
取得したデータのカラムを隠すには$hidden
を設定します。
例えば、Fruitモデルにデータを入れて、全てのデータをとって配列で出力してみます。
全てのデータを下記のように配列化して、ddで出力しました。
dd(Fruit::all()->toArray());
そうすると、このように出力されます。
^ array:3 [
0 => array:6 [
"id" => 1
"name" => "apple"
"color" => "orange"
"price" => "100"
"created_at" => "2022-05-04T10:11:59.000000Z"
"updated_at" => "2022-05-04T10:11:59.000000Z"
]
1 => array:6 [
"id" => 2
"name" => "banana"
"color" => "yellow"
"price" => "120"
"created_at" => "2022-05-04T10:11:59.000000Z"
"updated_at" => "2022-05-04T10:11:59.000000Z"
]
2 => array:6 [
"id" => 3
"name" => "orange"
"color" => "orange"
"price" => "150"
"created_at" => "2022-05-04T10:11:59.000000Z"
"updated_at" => "2022-05-04T10:11:59.000000Z"
]
]
created_at
・updated_at
・price
を隠す場合は、下記のようにモデルに設定します。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Fruit extends Model
{
use HasFactory;
protected $hidden = ['price', 'created_at', 'updated_at'];
protected $guarded = ['created_at', 'updated_at'];
}
$hiddenプロパティを用意して、表示しないカラムを指定しました。
こうすることで、先ほどと同じように出力すると、下記のようになります。
^ array:3 [
0 => array:3 [
"id" => 1
"name" => "apple"
"color" => "orange"
]
1 => array:3 [
"id" => 2
"name" => "banana"
"color" => "yellow"
]
2 => array:3 [
"id" => 3
"name" => "orange"
"color" => "orange"
]
]
指定したカラムのデータが返ってこないようになりました。
ちなみにcreateでデータを追加する場合は、hiddenに指定したカラムにもデータを入力することは可能です。
SQLをモデルに書くとスッキリ
モデルに任意のメソッドを作成して、Eloquentで発行するSQLをまとめておくことが可能です。
コントローラーに直接書くこともできますが、同じ内容を複数書く場合や長い場合は、コントローラーのソースコードが読みにくくなるのでモデルにまとめるとスッキリします。
例えば、先ほどのFruitモデルでcolorが赤色の物のみ抽出するクエリをモデルに書いてみます。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Fruit extends Model
{
use HasFactory;
protected $hidden = ['price', 'created_at', 'updated_at'];
protected $guarded = ['created_at', 'updated_at'];
public function fetchRedColorItems()
{
return $this::whereColor('red')->get();
}
}
fetchRedColorItemsメソッドを作成しました。
モデル内では$this
で自分のことを指すことが可能です。
$this::whereColor
で、Colorカラムに’red’が指定されているものだけ取ってきて、呼び出し元に返しています。
呼び出す時には、対象のモデルをnewしてからメソッドを呼ぶようにします。
$fruitModel = new Fruit();
dd($fruitModel->fetchRedColorItems()->toArray());
上記のようにして、newしたモデルのインスタンスから作成したメソッドを呼ぶことが可能です。
コメント