CakePHP2でテーブル名を動的に変える方法

この記事はだいぶ前に書かれたものなので情報が古いかもしれません
この画像の特に意味はないです

この記事を三行にまとめると

テーブル名を書き換えたい
useTableを書き換える
setSource()で書き換える
2023年にもなってCakePHP2系の話をするなんて「10年前からタイムスリップでもしてきたんか!?」と言われてしまいそうな感じですが、でも僕は未だにCakePHP2系を触る機会が少しばかりあるので、備忘録としてこの情報を残しておきたいと思います。

CakePHPの場合、モデルのテーブル名はこちらで明示的に変えない限り、命名規約に従って自動的に英単語の複数形がセットされます。

ではこのテーブル名を任意に変更したい場合はどうするか。方法は大きく分けて二つあります。



簡単なのは「$useTable」を書き換える方法です。

Sample extends AppModel {
  public $useTable = 'テーブル名';
}

コントローラーから変更したい場合も同様です。

$this->{$model}->useTable = 'テーブル名';

一応この方法でも問題はないんですが、場合によってはテーブルが上手く切り替わってくれないことがあります。



例えば「table1」「table2」「table3」みたいな名前のテーブルがあったとして、これをループ処理の中でこまめに切り替えたい場合。

for($i = 1; $i <= 3; $i++) {
  $this->{$model}->useTable = 'table'.$i;
  $data = $this->{$model}->find('all');
}

こんな感じでテーブルを切り替えながら何度もfindを実行するみたいなことをやるとき、useTableを書き換えるだけだと上手く切り替わってくれません。実際にやってみれば分かりますが上記の場合だと3回ともtable1のデータを参照しようとします。

おそらくですが、CakePHPはクエリをキャッシュする機能を持っているので、このように連続でfindをしようとするとキャッシュが効いちゃってテーブルが切り替わらないんじゃないかなと思います。

こういうときはsetSource()という関数を使うと切り替わってくれます。

for($i = 1; $i <= 3; $i++) {
  $this->{$model}->setSource('table'.$i);
  $data = $this->{$model}->find('all');
}

これでOKです。
 もしかしたら何か関連しているかも? 
 質問や感想などお気軽にコメントしてください