LaravelのModel(モデル)について
LaravelのModelは、データベースのデータ操作をするために作成します。
Modelを使用することで、例えばデータの取得や追加・更新・データの変換などを行うことができます。
基本的には、テーブルとモデルは1対1になります。
データベースの1つのテーブルにつき、ひとつのモデルを用意します。
Model(モデル)を作成する
artisanコマンドを使用することで、Modelを作成することができます。
今回は例としてMemberモデルを作成します。
php artisan make:model Member
実行結果キャプチャ
Modelはapp/Models/ディレクトリに作成されます。
Modelの命名規則について
Modelの命名規則はキャメルケースの単数形となります。
キャメルケースとは複数単語でModel名を構成する場合、各単語の先頭文字を大文字にする方式です。
キャメルケース単数形の例:MemberItem
補足:テーブルの命名規則
モデルに対するテーブル名の命名規則は、スネークケースの複数形となります。
スネークケースとは複数単語でテーブル名を構成する場合、各単語の間をアンダーバーにする方式です。
スネークケース複数形の例:member_items
おすすめ本
Model(モデル)に書くべき基本的な内容
まず、基本的なModelに書くべき内容のfiilableまたはguardedについて紹介します。
前提としてModelファイルをコマンドで作成したときは、デフォルトで下記のようになっています。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Member extends Model
{
use HasFactory;
}
デフォルトの状態に必要な記述を加えていきます。
fillableまたはguarded
データベースにデータを登録または更新したい場合は、fillableまたはguardedを記載する必要があります。
fillableはデータ登録、更新を許可するカラムを指定します。
guardedはデータ登録、更新を許可しないカラムを指定します。指定したカラム以外は許可されます。
例をあげて解説していきます。
fillableの設定例
membersテーブルには「名前」「メールアドレス」「電話番号」「住所」のカラムがあり、そのカラムにデータを登録または更新ができるようにModelで定義します。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Member extends Model
{
use HasFactory;
protected $fillable = [
'name',
'mail',
'tel',
'address',
]
}
このように設定することで、指定したカラムの登録または更新を許可します。
guardedの設定例
membersテーブルには「名前」「メールアドレス」「電話番号」「住所」のカラムがあり、そのカラムにデータを登録または更新ができるようにModelで定義します。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Member extends Model
{
use HasFactory;
protected $guarded = [
'id',
]
}
guardedにはidを指定しました。
idカラム以外の全てのカラムに対して、登録と更新を許可できます。
idは自動採番(AUTO_INCREMENT)を使用することが多く、idに対して登録または更新する処理をすることは基本的にはありません。
なのでguardedにidを指定する方法が良いのではないでしょうか。
fillableとguardedのどちらを使用すればよいか
結論、guardedを使用するべきだと思います。
fillableで指定すると、テーブルのカラム追加がされる度にfillableにカラムを定義する必要があります。
一方、guardedであればテーブルのカラムが増えてもguardedの改修をする必要がありません。
登録・更新メソッドについて
fillableまたはguardedのデータ登録または更新の許可が適用される代表的なメソッドは下記です。
create(登録処理をするメソッド)
update(更新処理をするメソッド)
fill + save (登録・更新処理をするメソッド)
Model(モデル)に書くことが多い内容をピックアップ
・カラムの型の定義
・親子関係の定義(リレーション)
・データベースのカラム取得時の値変換(アクセサ)
・データベースのカラム登録時の値変換 (ミューテタ)
型定義
$castsでカラムに対しての型を定義することが可能です。

データベースのテーブル作成時にカラムの型定義ってされてるけど、モデルで定義する必要があるんですか?

モデルの型定義をしない場合、例えば$query->first()でデータを取得した際にintegerで定義していたものもstringになってしまいます。
モデルで型を定義しておけば、データ取得時に指定した型で取得することが可能です。
型の定義の仕方は下記です。
protected $casts = [
'name' => 'string',
'price' => 'integer',
'flag' => 'boolean'
];
親子関係の定義(リレーション)
Modelでリレーションを定義することによってリレーション先にアクセスすることが簡単にできます。
メソッドによって定義できる内容が異なります。
hasOneメソッド
belongsToメソッド
hasManyメソッド
belongsToManyメソッド
hasOneメソッド
メソッドについて、親テーブルのusersテーブルと子テーブルのphonesテーブルを例にして解説します。
usersテーブル(親テーブル)とphonesテーブル(子テーブル)の関係は1対1です。
この場合の、親テーブルから見た子テーブルのリレーション定義はhasOneメソッドを使います。
Userモデル
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function phone()
{
return $this->hasOne('App\Models\Phone');
}
}
belongsToメソッド(1対1)
メソッドについて、親テーブルのusersテーブルと子テーブルのphonesテーブルを例にして解説します。
usersテーブル(親テーブル)とphonesテーブル(子テーブル)の関係は1対1です。
この場合の、子テーブルから見た親テーブルのリレーション定義はbelongsToメソッドを使います。
Phoneモデル
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function phone()
{
return $this->belongsTo('App\Models\User');
}
}
hasManyメソッド
メソッドについて、親テーブルのcompanysテーブルと子テーブルのemployeesテーブルを例にして解説します。
companysテーブル(親テーブル)とemployeesテーブル(子テーブル)の関係は1対多です。
この場合の、親テーブルから見た子テーブルのリレーション定義はhasManyメソッドを使います。
Companyモデル
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Company extends Model
{
public function employee()
{
return $this->hasMany('App\Models\Company');
}
}
belongsToメソッド(1対多)
メソッドについて、親テーブルのcompanysテーブルと子テーブルのemployeesテーブルを例にして解説します。
companysテーブル(親テーブル)とemployeesテーブル(子テーブル)の関係は1対多です。
この場合の、子テーブルから見た親テーブルのリレーション定義はbelongsToメソッドを使います。
belongsToは子テーブルから親テーブルのリレーションを定義する際に、1対1でも1対多でも使用されます。
Employeeモデル
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Employee extends Model
{
public function company()
{
return $this->belongsTo('App\Models\Employee');
}
}
belongsToManyメソッド
belongsToManyメソッドは複雑なので、別の記事で詳しく解説します。
データベースのカラム取得時の値変換(アクセサ)
アクセサとは、データベースからデータを取得する時に走る処理のことです。
データベースからデータを取得する時に、そのまま取得するのではなく変換処理をさせたい場合に便利です。
アクセサの使用例
例えば、データベースに氏名を「姓」と「名」の別カラムで保存させている状況で、「姓+名」でデータを取得したいとします。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $append = ['full_name'];
public function getFullNameAttribute()
{
return $this->first_name . " " . $this->last_name;
}
}
get○○Attributeでアクセサを定義します。
アクセサの命名規則はキャメルケースで記載するルールになっています。
(キャメルケース例:getFullNameAttribute)
上記のコードではgetFullNameAttributeでLaravelがアクセサであることを判断し、full_name属性を作成します。
実際に姓+名でデータが取得できるか試します。
$user->first(); $user->full_name;
アクセサの定義をしたfull_nameで「姓名」を取得することができるようになります。
データベースのカラム登録時の値変換 (ミューテタ)
ミューテタとは、データベースにデータを保存する時に走る処理のことです。
データベースからデータを保存する時に、そのまま保存するのではなく変換処理をさせたい場合に便利です。
ミューテタの使用例
例えば、データベースに氏名の「名」を大文字変換して登録したいとします。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function setFirstNameAttribute($value)
{
$this->attributes['first_name'] = strtoupper($value);
}
}
set○○Attributeでミューテタを定義します。
ミューテタの命名規則は先程と同様に、キャメルケースで記載するルールになっています。
(キャメルケース例:setNameAttribute)
strtoupperで$valueの値を大文字変換しています。
実際にデータを保存してみます。
$user = User::first();
$user->first_name = 'ken';
$user->save();
$user->first_nameを保存する時に、UserモデルのsetFirstNameAttributeの処理を通過して大文字変換されてデータが保存されます。
コメント