Laravel 基礎学習/Model の仕組みと書き方
Laravel の Model は、データベース操作を担当する重要な仕組み。
本記事では、Model の役割や作成方法、基本的な DB 操作やリレーションについて解説する。
Model とは
Laravel の Model は、
データベース操作を担当する PHP クラス。
Laravel では、
DB テーブルを直接操作するのではなく、
Model を通してデータを扱うのが基本。
Laravel では、
基本的に以下の流れで処理が行われる。
ブラウザアクセス
Route
URL に対応する Controller を決定
Controller
必要な処理を実行
Model
DB操作が必要な場合に利用する
View
ブラウザへ表示する HTML を生成
ブラウザへ表示
Model では、
- DB からデータを取得する
- DB にデータを保存する
- DB のデータを更新する
- DB のデータを削除する
- テーブル同士の関係(リレーション)を扱う
などを行う。
例えば、
- users テーブル → app/Models/User.php
- posts テーブル → app/Models/Post.php
- comments テーブル → app/Models/Comment.php
のように、
テーブルごとに、
DB 操作を担当する PHP ファイル(Model)を作成する。
また、
Laravel の Model では、
テーブル同士の関係(リレーション)も定義できる。
例えば、
- users テーブルの1人のユーザーは複数の投稿を持つ
- posts テーブルの投稿は1人のユーザーに属する
といった関係を、
Model に記述できる。
これにより、
$user->posts
のように記述するだけで、
そのユーザーに紐づく posts テーブルのデータを取得できる。
Laravel では、
リレーションを定義することで、
SQL を直接書かなくても関連データを取得できる。
SQL のイメージで言うと、
Laravel が内部で以下のような SQL を自動実行している。
SELECT * FROM posts
WHERE user_id = 1;
Laravel では、
テーブル名を複数形、
Model 名を単数形(先頭大文字)にするのが基本。
Laravel は、
この命名規則を使って、
Model と DB テーブルを自動で紐づけしている。
Model を実行するには
Model は、
単体で画面表示されるものではない。
Laravel では、
主に Controller などから Model を呼び出し、
DB 操作を実行する。
例
class PostController extends Controller
{
public function index()
{
$posts = Post::all();
return view('posts.index', compact('posts'));
}
}
この例では、
- Controller が Model を呼び出す
- Model が DB からデータを取得する
- 取得したデータを View へ渡す
という流れで処理が動作している。
Model を作成する
Laravel では、
Model ファイルを
app/Models
フォルダ内へ配置する。
このフォルダは、
Laravel プロジェクト作成時に最初から自動作成される。
Model は、
通常の PHP ファイルとして手動作成することもできる。
ただし Laravel では、
Artisan コマンドを使って作成することが多い。
Artisan を使用すると、
Laravel の定型コードを自動生成できる。
例えば、
namespace や class 定義などを、
最初から Laravel の形式で作成してくれる。
実行場所
ターミナルで Laravel プロジェクトフォルダへ移動してから実行する。
例
cd ~/Herd/bbs-app
実行コマンド
php artisan make:model Post
正常に作成された場合
正常に実行されると、
以下の場所に Model ファイルが作成される。
app/Models/Post.php
命名規則
Laravel の Model は、
基本的に単数形で命名する。
例
User
Post
Comment
Category
Laravel では、
テーブル名を複数形、
Model 名を単数形にするのが基本。
例
- users → User
- posts → Post
- comments → Comment
Laravel は、
この命名規則を使って、
Model とテーブルを自動で紐づけしている。
また、
Model 名は、
クラス名の先頭を大文字にする
PascalCase(パスカルケース)が一般的。
例
Post.php
なお、
Model のファイル名と、
そこに記述するクラス名は一致させる必要がある。
例
class Post extends Model
{
}
この場合、
ファイル名も
Post.php
にする。
複数の Model を作成する例
php artisan make:model User && \
php artisan make:model Post && \
php artisan make:model Comment && \
php artisan make:model Category && \
php artisan make:model Like
Laravel では、
テーブルごとに Model を作成していくことが多い。
Model の基本形
Laravel の Model は、
基本的に以下のような形で書く。
例
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $table = 'posts';
protected $fillable = [
'title',
'body',
];
}
各コードの役割
namespace
namespace App\Models;
namespace は、
この Model の所属場所を表す記述。
Laravel では、
フォルダ構成と対応する形で namespace を設定することが多い。
例えば、
namespace App\Models;
の場合、
app/Models
に配置される Model であることを表している。
namespace を使うことで、
同じ名前のクラスが存在しても、
「どのクラスなのか」を区別できる。
extends Model
class Post extends Model {}
extends Model は、
Laravel にあらかじめ用意されている
Model 用の機能を使用するための記述。
Laravel の Model は、
基本的にこの形で作成する。
例えば、
- DB データの取得
- DB データの保存
- リレーション
- create()
- update()
など、
Laravel の Model 用機能を使用できるようになる。
なお、
extends Model を書かなくても、
単純な PHP クラスとして動作する場合はある。
ただし、
Laravel の Model 用機能が使用できなくなるため、
基本的には extends Model を付けて作成する。
protected $table
protected $table = 'posts';
$table は、
この Model が操作するテーブル名を指定する設定。
この場合 Model は、
posts テーブルを操作する。
Laravel の命名規則に沿っている場合は、
$table を省略できることもある。
例えば、
- Post → posts
- User → users
のような場合、
Laravel が自動でテーブル名を判定する。
protected $fillable
protected $fillable = [
'title',
'body',
];
$fillable は、
DB に保存してよいカラムを指定する設定。
これを設定することで、
Post::create([
'title' => 'タイトル',
'body' => '本文',
]);
のような create() 処理を安全に使用できる。
Laravel では、
$fillable に指定していないカラムは、
create() や update() でまとめて保存できない。
これは、
意図しないデータ更新を防ぐための安全機能。
よく使う Model の設定
Laravel の Model では、
DB 操作の挙動を制御するための様々な設定を行える。
ここでは、
初心者のうちによく使う設定を紹介する。
$table とは
protected $table = 'posts';
$table は、
この Model が操作するテーブル名を指定する設定。
この場合、
Post Model は、
posts テーブルを操作する。
Laravel の命名規則に沿っている場合は、
$table を省略できることもある。
例えば、
- Post → posts
- User → users
- Comment → comments
のような場合、
Laravel が自動でテーブル名を判定する。
一方、
命名規則に沿っていない場合は、
$table を使って明示的に指定する必要がある。
例
protected $table = 'blog_post_data';
この場合、
Post Model は、
blog_post_data
テーブルを操作する。
$fillable とは
protected $fillable = [
'title',
'body',
];
$fillable は、
DB に保存してよいカラムを指定する設定。
これを設定することで、
Post::create([
'title' => 'タイトル',
'body' => '本文',
]);
のような create() 処理を安全に使用できる。
Laravel では、
$fillable に指定していないカラムは、
create() や update() でまとめて保存できない。
これは、
意図しないデータ更新を防ぐための安全機能。
$timestamps とは
public $timestamps = true;
$timestamps は、
Model の設定値として使用するプロパティ。
DB テーブルの created_at と updated_at を
自動管理する設定。
Laravel では、
デフォルトで有効になっている。
そのため、
通常は記述しなくても動作する。
create() や update() を実行すると、
Laravel が自動で日時を更新する。
一方、
created_at や updated_at を使わない場合は、
false に設定する。
例
public $timestamps = false;
$primaryKey とは
protected $primaryKey = 'post_id';
$primaryKey は、
主キーとなるカラム名を指定する設定。
Laravel では、
デフォルトで
id
カラムを主キーとして扱う。
そのため、
通常は省略できる。
ただし、
主キー名が id 以外の場合は、
$primaryKey を使って指定する必要がある。
例
protected $primaryKey = 'user_id';
この場合、
user_id
が主キーとして扱われる。
Model でリレーションを扱う
Laravel の Model では、
テーブル同士の関係(リレーション)を定義できる。
リレーションは、
Laravel 独自の特殊な機能ではなく、
元々 DB に存在するテーブル同士の関係を表すもの。
Laravel では、
リレーションを定義することで、
SQL を長く書かなくても、
関連データを簡単に取得できる。
例えば、
- 1人のユーザーが複数の投稿を持つ
- 1つの投稿が1人のユーザーに属する
といった関係を、
Model にメソッドとして記述する。
Laravel では、
リレーションを定義することで、
SQL を直接書かなくても関連データを取得できる。
ここでは、
実務でも特によく使われる以下の4種類を紹介する。
- 1対多(hasMany)
- 多対1(belongsTo)
- 1対1(hasOne)
- 多対多(belongsToMany)
1対多(hasMany)
hasMany は、
「1つに対して複数ある関係」を表すリレーション。
例えば、
- 1人のユーザーが複数の投稿を持つ
という関係を表現できる。
User Model 側
class User extends Model
{
public function posts()
{
return $this->hasMany(Post::class);
}
}
この posts() メソッドは、
users テーブルと posts テーブルの
1対多リレーションを表している。
これにより、
$user->posts
のように記述するだけで、
そのユーザーに紐づく投稿一覧を取得できる。
例
$user = User::find(1);
$user->posts;
Laravel では、
User::find(1)
と書くことで、
id が 1 の users データを取得できる。
SQL のイメージで言うと、
以下に近い処理。
SELECT * FROM users
WHERE id = 1
LIMIT 1;
次に、
$user->posts
と書くと、
Laravel が内部で以下のような SQL を自動実行する。
SELECT * FROM posts
WHERE user_id = 1;
つまり、
users から id=1 のユーザーを取得し、
そのユーザーに紐づく posts テーブルのデータを自動取得している。
多対1(belongsTo)
belongsTo は、
「複数が1つに属する関係」を表すリレーション。
例えば、
- 複数の投稿が1人のユーザーに属する
という関係を表現できる。
Post Model 側
class Post extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
この user() メソッドは、
posts テーブルと users テーブルの
多対1リレーションを表している。
これにより、
$post->user
のように記述するだけで、
その投稿を作成したユーザーを取得できる。
例
$post = Post::find(1);
$post->user;
SQL のイメージで言うと、
Laravel が内部で以下のような SQL を実行している。
SELECT * FROM users
WHERE id = posts.user_id
LIMIT 1;
つまり、
投稿データから user_id を取得し、
対応する users データを自動取得している。
1対1(hasOne)
hasOne は、
「1つに対して1つだけ関連する関係」を表すリレーション。
例えば、
- 1人のユーザーが1つのプロフィールを持つ
といった関係を表現できる。
User Model 側
class User extends Model
{
public function profile()
{
return $this->hasOne(UserProfile::class);
}
}
これにより、
$user->profile
のように記述するだけで、
そのユーザーに紐づくプロフィール情報を取得できる。
多対多(belongsToMany)
belongsToMany は、
「複数と複数が関連する関係」を表すリレーション。
例えば、
- 1つの投稿に複数のタグが付く
- 1つのタグが複数の投稿に付く
といった関係を表現できる。
多対多では、
中間テーブルを使用する。
例
posts
↕
post_tag
↕
tags
中間テーブルには、
それぞれの ID を保存する。
中間テーブル例
post_tag
post_id
tag_id
Post Model 側
class Post extends Model
{
public function tags()
{
return $this->belongsToMany(Tag::class);
}
}
これにより、
$post->tags
のように記述するだけで、
その投稿に紐づくタグ一覧を取得できる。
まとめ:Model は DB の操作を担当
Laravel の Model は、
DB 操作を担当する重要な仕組み。
Model を使うことで、
- DB データの取得
- DB データの保存
- DB データの更新
- DB データの削除
などを、
PHP から簡潔に扱えるようになる。
また、
リレーションを定義することで、
テーブル同士の関係も簡単に扱える。
Laravel では、
Route
↓
Controller
↓
Model
↓
View
の流れで処理が動作する。
まずは、
Model を通して DB を操作する基本的な流れを理解することが重要。