ウェブサービスを作っています。

isUnique がバグっている件

1 リクエスト中に複数レコード保存していて cacheQueries を使っていると、validation の isUnique ルールが効かないことがあります。


テーブル定義

CREATE TABLE users (name VARCHAR(255));

app/models/user.php

<?php
class User extends AppModel
{
    public $cacheQueries = true;
    public $validate = array('name' => array('rule' => 'isUnique'));
}

app/controllers/users_controller.php

<?php
class UsersController extends AppController
{
    public function index()
    {
        for ($i = 0; $i < 2; $i++) {
            $this->User->create();
            $this->User->save(array('User' => array('name' => 'same')));
        }
    }
}

結果

mysql> SELECT * FROM users;
+------+
| name |
+------+
| same |
| same |
+------+
2 rows in set (0.00 sec)

修正版

AppModel などに書いてオーバーライド。
本当は CakePHP 本家に伝えた方がいいですね。

<?php
class AppModel extends Model
{
    public function isUnique($fields, $or = true)
    {
        $originalCacheQueries = $this->cacheQueries;

        $this->cacheQueries = false;
        $result = parent::isUnique($fields, $or);
        $this->cacheQueries = $originalCacheQueries;

        return $result;
    }
}