#CakePHP3 EntityのsetでDBの型によってはまったこと
今日、普通にCakePHP3を書いてたわけですが、
patchEntityすると、データが消えるという謎現象が発生したわけですね。
具体的に起きたこと
public function index()
{
$a = $this->Topics->newEntity();
$b = [];
$b['tiny1'] = true;
$b['tiny4'] = true;
$b['timestamp'] = '2016-01-01 00:00:00';
$b['datetime'] = '2016-01-01 00:00:00';
$a = $this->Topics->patchEntity($a, $b);
debug($a);
}
こんな感じなコードがあったとして、Entity先のDBのカラムはカラム名の通り、それぞれ、tinyint(1)
,tinyint(4)
,timestamp
,datetime
なわけですよ。
その結果返ってくる結果がこれ
object(App\Model\Entity\Topic) {
'tiny1' => true,
'timestamp' => object(Cake\I18n\Time) {
'time' => '2016-01-01T00:00:00+00:00',
'timezone' => 'UTC',
'fixedNowTime' => false
},
(以下略)
tiny(4)
とdatetime
のデータが返ってきません。
さらに、以下のようにfind後にpatchEntityをした場合だと・・・
public function index()
{
$a = $this->Topics->find('all')->first();
$b = [];
$b['tiny1'] = true;
$b['tiny4'] = true;
$b['timestamp'] = '2016-01-01 00:00:00';
$b['datetime'] = '2016-01-01 00:00:00';
$a = $this->Topics->patchEntity($a, $b);
debug($a);
}
object(App\Model\Entity\Topic) {
'tiny1' => true,
'tiny4' => null,
'timestamp' => object(Cake\I18n\Time) {
'time' => '2016-01-01T00:00:00+00:00',
'timezone' => 'UTC',
'fixedNowTime' => false
},
'datetime' => null,
なんかnull
になってるーーーーーーー!?
何が起きているか
entityのsetが走るタイミングでデータの変換が行われているのですが(このへん)、型の中で想定外のものは全部nullに変換されています。(この辺とか)
今回の場合、tinyintの場合だと、桁数が1の場合はboolean,桁数が4の場合はintegerと判定されたため、tinyint(4)ではtrue
は想定外のデータなのでnull
という動作をしています。
tinyint
はCakePHP2だと確か、桁数によらずboolean的な動作をしてたので、そのノリで使ってたら動かない!的なことになったわけですね。
日時については、timestamp
は文字列でも普通にいけるんですが、datetime
の場合はちゃんとtimeクラスのオブジェクトにしておかないとnull
を返されてしまいます。。。
まとめ
とりあえず現状こんな問題が出てきたのはmysqlばっかりなんですけど。。。
postgresは特に今のところこんな話は出てきていません。
まぁDB設計はちゃんとしましょうってお話なんですが()