はじめに
今回はCodeIgniterで用意されているModelクラスについて説明します。
Modelは、単一のテーブルを便利に扱うための機能を提供するクラスです。
クエリビルダだと煩雑になりやすい各CRUD操作が楽になったりします!
Modelクラスの説明-設定
まず、設定系のプロパティについて、説明していきます。
<?php
namespace App\Models;
use CodeIgniter\Model;
class UserModel extends Model
{
protected $table = 'users';
protected $primaryKey = 'user_id';
protected $useAutoIncrement = false;
protected $returnType= 'array';
//protected $returnType = User::class;
protected $useSoftDeletes = true;
protected $allowedFields = [
'username',
'email',
'password',
];
protected bool $allowEmptyInserts = false;
// date property
protected $useTimestamps = true;
protected $dateFormat = 'datetime';
protected $createdField = 'created_at';
protected $updatedField = 'updated_at';
protected $deletedField = 'deleted_at';
}
$table
利用するテーブル物理名を設定するプロパティです。
必ず設定する必要があります。
$primaryKey
テーブルのプライマリーキーを設定するプロパティです。
デフォルトはid
なので、ほとんどのテーブルでは設定しなくても問題ありませんが、
id以外のカラムをPKにする場合は、必ず設定する必要があります。
$useAutoIncrement
オートインクリメント機能を利用するか設定するプロパティです。
デフォルトはtrue
なので、ほとんどのテーブルでは設定しなくても問題ありませんが、
オートインクリメントではないカラムをPKにする場合は、false
に設定する必要があります。
$returnType
CRUD実行時に返却される結果の形式を設定するプロパティです。
デフォルトはarray
なので配列形式で返されますが、Entity形式も指定できます。
Modelクラスではなく、クエリビルダでデータを取得すると、codeIgniter\Database\MySQLi\Result
のようにResultオブジェクトが返されます。
$useSoftDeletes
delete()でのレコード削除を論理削除にするか設定するプロパティです。
デフォルトはfalse
なので、物理削除テーブルとして扱われます。
true
に設定すると論理削除になるだけでなく、find()による取得時も論理削除されたデータは取得されないような条件でSQLが構築されます。
$deletedFieldで指定したカラムが論理削除の判断に利用されるので、必ずNULL許可のカラムでなければなりません。
$allowedFields
登録/更新を許可するカラムを設定するプロパティです。
指定されていないカラムは値をセットしていても無視されるので、意図しないカラムの更新を防ぐことが出来ます。
なお、取得には影響しません。
$createdField、$updatedField、deletedField
に設定したカラムは、$allowedFieldsに設定しなくても更新されるため、設定不要です。
プライマリーキーは更新されてはいけないので、絶対に指定しないでください。
$allowEmptyInserts
空データのinsertを許容するか設定するプロパティです。
デフォルトはfalse
なので、許容されません。
何かしらの理由で。空データをまず登録した後で必要な値に更新したいケースがあれば、利用することがありそうですが、基本的には利用しないと思います。
$useTimestamps
登録や更新に、現在日付を自動的に登録するか設定するプロパティです。
デフォルトはfalse
です。
true
にした場合は、$dateFormat
で指定した形式で自動的に登録します。
$dateFormat
自動登録する日付の型を設定するプロパティです。
デフォルトはdatetime
ですが、他にもdate
かint
が設定できます。
$createdField
登録日時に現在日時を登録するカラムを設定するプロパティです。
デフォルトは、created_at
です。
$updatedField
更新日時に現在日時を登録するカラムを設定するプロパティです。
デフォルトは、updated_at
です。
$deletedField
削除日時に現在日時を登録するカラムを設定するプロパティです。
デフォルトは、deleted_at
です。
Modelクラスの説明-バリデーション
次に、モデルを利用した登録/更新時にバリデーションを行う際の各種設定です。
<?php
namespace App\Models;
use CodeIgniter\Model;
class UserModel extends Model
{
protected $validationRules = [
'username' => 'required|max_length[30]|alpha_numeric_space|min_length[3]',
'email' => 'required|max_length[254]|valid_email|is_unique[users.email]',
'password' => 'required|max_length[255]|min_length[8]',
'pass_confirm' => 'required_with[password]|max_length[255]|matches[password]',
];
protected $validationMessages = [
'email' => [
'is_unique' => '既に登録されているメールアドレスです。',
],
];
protected $skipValidation = false;
protected $cleanValidationRules = true;
}
$validationRules
バリデーションルールを配列形式で設定するプロパティです。
デフォルトは、[]
です。
$validationMessages
バリデーションエラー時のメッセージを配列形式で設定するプロパティです。
デフォルトは、[]
です。
$skipValidation
登録/更新時にバリデーションを行うか設定するプロパティです。
デフォルトは、false
なのでバリデーションは行います。
ただ、前述の$validationRules
を指定しないと行われません。
$cleanValidationRules
渡されたデータに存在しないバリデーションルールは、バリデーション対象から除外するか設定するプロパティです。
デフォルトはtrue
なので除外されます。
更新時に一部カラムだけ更新したい場合に、trueにしておけばバリデーションエラーを回避できます。
Modelクラスの説明-コールバック
次に、モデルを利用した各CRUD操作時に行えるコールバックです。
こちらは簡単な紹介のみになります。
<?php
namespace App\Models;
use CodeIgniter\Model;
class UserModel extends Model
{
protected $allowCallbacks = true;
protected $beforeInsert = [];
protected $afterInsert = [];
protected $beforeUpdate = [];
protected $afterUpdate = [];
protected $beforeFind = [];
protected $afterFind = [];
protected $beforeDelete = [];
protected $afterDelete = [];
}
$allowCallbacks
コールバック処理を許可するか設定するプロパティです。
デフォルトはtrue
なので、コールバック処理が実装されていれば実行されます。
$beforeInsert、$beforeUpdate、$beforeFind、$beforeDelete
それぞれ、登録/更新/取得/削除前
に行う処理を記載するメソッドです。
メソッドに渡される引数はそれぞれ異なります。詳しくはこちら
$afterInsert、$afterUpdate、$afterFind、$afterDelete
それぞれ、登録/更新/取得/削除後
に行う処理を記載するメソッドです。
beforeと同様、メソッドに渡される引数はそれぞれ異なります。
Modelクラスの説明-CRUDメソッド
最後に、モデルを利用した各CRUD操作時を行える各メソッドです。
find($pk)
PKを条件にデータを取得するメソッドです。
論理削除されたデータは取得されません。
$user = $userModel->find(1); // PKで単一取得
$user = $userModel->find([1, 2]); // PKで複数取得
// SELECT * FROM `users` WHERE `users`.`deleted_at` IS NULL AND `users`.`id` IN (1,2)
findColumn($columeName)
単一カラムの取得を行うメソッドです。
論理削除されたデータは取得されません。
$user = $userModel->findColumn('login_id');
// SELECT `login_id` FROM `users` WHERE `users`.`deleted_at` IS NULL
findAll($limit, $offset)
全てのデータを取得するメソッドです。
条件を絞りたい場合はクエリビルダーのwhereなどを利用します。
論理削除されているデータは取得されません。
$user = $userModel->where('user_code', 'test')->findAll();
// SELECT * FROM `users` WHERE `user_code` = 'test' AND `users`.`deleted_at` IS NULL
first()
1件データを取得するメソッドです。
条件を絞りたい場合はクエリビルダーのwhereなどを利用します。
論理削除されているデータは取得されません。
$user = $userModel->where('user_code', 'test')->first();
// SELECT * FROM `users` WHERE `user_code` = 'test' AND `users`.`deleted_at` IS NULL LIMIT 1
withDeleted()
論理削除されたデータも取得したい時に利用するメソッドです。
$user = $userModel->where('user_code', 'test')->withDeleted()->findAll();
// SELECT * FROM `users` WHERE `user_code` = 'test'
onlyDeleted()
論理削除されたデータのみ取得したい時に利用するメソッドです。
$user = $userModel->onlyDeleted()->where('user_code', 'test')->findAll();
// SELECT * FROM `users` WHERE `user_code` = 'test' AND `users`.`deleted_at` IS NOT NULL
insert($data)
新規登録したい場合に利用するメソッドです。
$data = [
'login_id' => 'user1',
'password' => 'password',
];
$userModel->insert($data); // return PK
$userModel->insert($data, false); // returnクエリ成否。成功(true)、失敗(false)
$userModel->getInsertID(); // return 登録したPKの値
// INSERT INTO `users` (`login_id`, `password`, `created_at`, `updated_at`) VALUES ('user1', 'password', '2024-04-23 09:20:33', '2024-04-23 09:20:33')
allowEmptyInserts()
空のデータを新規登録したい場合に利用するメソッドです。
$userModel->allowEmptyInserts()
// created_at, updated_atの自動登録をモデルで設定している場合
// INSERT INTO `users` (`created_at`, `updated_at`) VALUES ('2024-04-23 09:33:57', '2024-04-23 09:33:57')
// created_at, updated_atの自動登録をモデルで設定していない場合
// INSERT INTO `users` VALUES ()
update($pk, $data)
データを更新したい場合に利用するメソッドです。
$data = [
'login_id' => 'user1',
'password' => 'password',
];
$userModel->update(1, $data); // return クエリ成否。返り値は成功(true)、失敗(false)。
// UPDATE `users` SET `login_id` = 'user1', `password` = 'password' WHERE `users`.`id` IN (1)
$userModel->update([10, 11, 12], $data); // 更新処理を実施
// UPDATE `users` SET `login_id` = 'user1', `password` = 'password' WHERE `users`.`id` IN (10,11,12)
$userModel->where('name', '山田')->set($data)->update(); // 主キー以外のupdateをしたい場合
// UPDATE `users` SET `login_id` = 'user1', `password` = 'password' WHERE `name` = '山田'
$userModel->set($data)->update(); // 更新処理を実施
// 4.3からwhereを指定しないとエラーになります
// Updates are not allowed unless they contain a "where" or "like" clause
save()
insert()/update()のラッパーで、PKが指定されていれば更新、されていなければ新規登録するメソッドです。
$data = [
'login_id' => 'user1',
'password' => 'password',
];
$userModel->save($data); // 新規登録。return クエリ成否。返り値は成功(true)、失敗(false)
// INSERT INTO `users` (`login_id`, `password`) VALUES ('user1', 'password')
$data = [
'id' => 10,
'login_id' => 'user1',
'password' => 'password',
];
$userModel->save($data); // 更新
// UPDATE `users` SET `login_id` = 'user1', `password` = 'password' WHERE `users`.`id` IN (10)
delete()
データを削除したい場合に利用するメソッドです。
$useSoftDeletesが設定されていれば論理削除、されていなければ物理削除になります。
$userModel->delete(1); // PKで単一削除。return クエリ成否。返り値は成功(true)、失敗(false)。
// UPDATE `users` SET `deleted_at` = '2024-04-23 10:11:36' WHERE `id` IN (1) AND `deleted_at` IS NULL
$userModel->delete([1, 2]); // PKで複数削除
// UPDATE `users` SET `deleted_at` = '2024-04-23 10:12:14' WHERE `id` IN (1,2) AND `deleted_at` IS NULL
$userModel->where('login_id', 'user1')->delete(); // PK以外の条件場合はクエリビルダーのwhere等を使う
// UPDATE `users` SET `deleted_at` = '2024-04-23 10:13:00' WHERE `login_id` = 'user1' AND `deleted_at` IS NULL
purgeDeleted()
論理削除されたデータを全て物理削除するメソッドです。
$userModel->purgeDeleted();
// DELETE FROM `users` WHERE `users`.`deleted_at` IS NOT NULL
モデルクラスの説明-おまけ
chunk()
バッチなどで大量のデータを処理する場合にメモリが枯渇しないように、分割取得して処理したい場合に利用するメソッドです。
$userModel->where('company_code', 1)->chunk(2, static function ($data) {
// 何かしらの処理
});
// 取得するデータが5件ある場合
// SELECT COUNT(*) AS `numrows` FROM `users` WHERE `company_code` = 1
// SELECT * FROM `users` WHERE `company_code` = 1 LIMIT 2
// SELECT * FROM `users` WHERE `company_code` = 1 LIMIT 2, 2
// SELECT * FROM `users` WHERE `company_code` = 1 LIMIT 4, 2
protect()
一時的に$allowedFields
を無視して、登録/更新したい際に利用するメソッドです。
seedでのテストデータ登録などで利用しますが、通常は使わないようにしましょう。
$userModel->protect(false)->insert($data)->protect(true); // シード実施時など、一時的に
asArray()、asObject()
$returnTypeに指定した形式以外で取得したい場合に利用するメソッドです。
$userModel->asArray()->where('status', 'active')->findAll();
$userModel->asObject()->where('status', 'active')->findAll();
クエリビルダーの呼び出し
モデルからクエリビルダーのメソッドは呼び出すことが出来ます。
(ビルダーからモデルのメソッドは呼び出すことは出来ません)
$userModel->builder();
$userModel->builder('books'); // 別テーブルのビルダーを取得
おわりに
CodeIgniterのModelについて、説明しました。
Modelと前の記事で紹介したEntityを使えば、DB操作周りの開発が加速しそうですね😃