体調不良で大遅刻しました・・・
申し訳ないです。
さて、
CodeIgniter4のクエリビルダにはCodeigniter3にもあった、ビルド中のクエリを取得するメソッドがある。
それが getCompiledSelect
というメソッド(Codeigniter3では get_compiled_select
)だが、これ、モデル中でも利用できて便利!
と思うじゃん?
実際取得してみるとあれ?となる。
namespace App\Models;
use CodeIgniter\Model;
class ItemModel extends Model {
protected $table = 'items';
protected $primaryKey = 'item_no';
protected $returnType = 'array';
protected $useSoftDeletes = true;
protected $allowedFields = [];
protected $useTimestamps = false;
protected $createdField = 'created_at';
protected $updatedField = 'updated_at';
protected $deletedField = 'deleted_at';
protected $validationRules = [];
protected $validationMessages = [];
protected $skipValidation = false;
protected $afterFind = [];
}
$itemModel = model('ItemModel');
$itemModel->select('item_no');
echo $itemModel->getCompiledSelect(false);
// SELECT `item_no` FROM `items`
// 実行してからgetLastQueryしてみると
$itemModel->find();
echo $itemModel->getLastQuery();
// SELECT `item_no` FROM `items` WHERE `items`.`deleted_at` IS NULL
つまり、モデル中の useSoftDelete
が適用されないということ。
Codeigniter3は useSoftDelete
なる機能がなかった(というか、モデルとDBがFW上で紐付いていなかった)ため、論理削除のクエリもクエリビルダに含めてから get_compiled_select
をするため、まず間違えることはないのだが、Codeigniter4のモデル機能に甘えてこれを忘れてしまうと 大変なことになる ので要注意。
まとめ:論理削除を用いたモデルを利用する場合は getCompiledSelect を使わずにクエリを実行してから getLastQuery をしよう(もしくは論理削除のwhere句を記述する)
※ 本当は getCompiledSelect
を使わないように設計するのが一番いいのだが、そうは行かないケースは結構あるわけで・・・
解決編: getCompiledSelect で useSoftDelete が効くようにする
https://qiita.com/bananacoffee/items/1b9b56ce541174a3fb7d